eternity_zzy
eternity_zzy
采纳率100%
2017-11-01 02:14 阅读 2.2k
已采纳

springBoot集成mybatis与shiro

2

最近在做一个springBoot集成mybatis与shiro的Demo 但是遇到shiro验证用户名密码一直提示不正确,实在是搞不明白,demo奉上http://pan.baidu.com/s/1jI3m9ZC,望解答,谢谢。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    r562253897 独家de记忆 2017-11-01 05:34

    简单的对你的代码修改了下,以下贴出:
    1.首先你的ShiroAction.userLogin,补货异常,不是你那么使用的。

     @RestController
    public class ShiroAction {
        private static final Logger logger = LoggerFactory.getLogger(ShiroAction.class);
        /**
         * 
         * @Title: userLogin
         * @Description: 用户登录
         * @return
         */
        @RequestMapping(value="/login",method=RequestMethod.POST)
        public String userLogin(HttpServletRequest request,String username, String password, Map<String, Object> map) {
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            String msg=null;
            try {
                logger.info("对用户[" + username + "]进行登录验证..验证开始");  
                subject.login(token);  
                logger.info("对用户[" + username + "]进行登录验证..验证通过");  
            }catch(UnknownAccountException uae){  
                logger.info("对用户[" + username + "]进行登录验证..验证未通过,未知账户");  
                msg = "未知账户";  
            }catch(IncorrectCredentialsException ice){  
                logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误的凭证");  
                msg = "密码不正确";  
            }catch(LockedAccountException lae){  
                logger.info("对用户[" + username + "]进行登录验证..验证未通过,账户已锁定");  
                msg = "账户已锁定";  
            }catch(ExcessiveAttemptsException eae){  
                logger.info("对用户[" + username + "]进行登录验证..验证未通过,错误次数过多");  
                msg = "用户名或密码错误次数过多";  
            }catch(AuthenticationException ae){  
                //通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
                logger.info("对用户[" + username + "]进行登录验证..验证未通过,堆栈轨迹如下");  
                ae.printStackTrace();  
                msg = "用户名或密码不正确";  
            }  
            map.put("msg", msg);
            //验证是否登录成功  
            if(subject.isAuthenticated()){  
                logger.info("用户[" + username + "]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)");  
                return "/login";
            }else{  
                token.clear();  
                return "/login";
            }  
        }
    }
    

    MyRealm.中的验证代码:

     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
            System.out.println("使用了自定义的realm,用户认证...");
            System.out.println("用户名:" + ((UsernamePasswordToken) token).getUsername());
            System.out.println("密码:" + new String(((UsernamePasswordToken) token).getPassword()));
    
            // 获取用户名
            String userName = (String) token.getPrincipal();
            // 依据用户名去数据库查询
            // 查询到了数据,验证密码是否正确
            // 密码正确,认证通过
            // 密码错误,认证失败
            // 没有查询到数据,认证失败
            sysUser su = new sysUser();
            su.setLoginName(userName);
            su = sysUserserviceImpl.selectByPrimaryKey(su);
            SimpleAuthenticationInfo SimpleAuthenticationInfo = new SimpleAuthenticationInfo(su.getLoginName(), su.getPassword(), this.getName());
            return SimpleAuthenticationInfo;
        }
    

    最后,最关键的一点,你的密码明文传输到shiro,并未使用加密处理,但是数据库中的密码却使用了加密,修改方法,就是在ShiroAction的UsernamePasswordToken生成之前对密码加密,当然,靠谱的是在前端就加密处理;

    我在你这个例子上面,密码框直接贴数据库加密后的串,点击登陆:
    以下是执行日志:

     2017-11-01 13:34:26.224  INFO 11232 --- [nio-8080-exec-9] com.kfit.zzy.controller.ShiroAction      : 对用户[admin]进行登录验证..验证开始
    使用了自定义的realm,用户认证...
    用户名:admin
    密码:d3c59d25033dbf980d29554025c23a75
    2017-11-01 13:34:26.228  INFO 11232 --- [nio-8080-exec-9] com.kfit.zzy.controller.ShiroAction      : 对用户[admin]进行登录验证..验证通过
    2017-11-01 13:34:26.228  INFO 11232 --- [nio-8080-exec-9] com.kfit.zzy.controller.ShiroAction      : 用户[admin]登录认证通过(这里可以进行一些认证通过后的一些系统参数初始化操作)
    
    
    点赞 评论 复制链接分享
  • eternity_zzy eternity_zzy 2017-11-03 10:12

    在ShiroFilterFactoryBean加上一下代码就可以了
    @Bean
    public SecurityManager securityManager(){
    DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    //设置realm.
    securityManager.setRealm(myShiroRealm());

        //注入缓存管理器;
        securityManager.setCacheManager(ehCacheManager());//这个如果执行多次,也是同样的一个对象;
    
        //注入记住我管理器;
        //securityManager.setRememberMeManager(rememberMeManager());
    
        return securityManager;
    }
    
    /**
     * 身份认证realm;
     * (这个需要自己写,账号密码校验;权限等)
     * @return
     */
    @Bean
    public MyShiroRealm myShiroRealm(){
        MyShiroRealm myShiroRealm = new MyShiroRealm();
        myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());;
        return myShiroRealm;
    }
    
    /**
     * shiro缓存管理器;
     * 需要注入对应的其它的实体类中:
     * 1、安全管理器:securityManager
     * 可见securityManager是整个shiro的核心;
     * @return
     */
    @Bean
    public EhCacheManager ehCacheManager(){
        System.out.println("ShiroConfiguration.getEhCacheManager()");
        EhCacheManager cacheManager = new EhCacheManager();
        cacheManager.setCacheManagerConfigFile("classpath:config/ehcache-shiro.xml");
        return cacheManager;
    }
    
    /**
     * 凭证匹配器
     * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了
     *  所以我们需要修改下doGetAuthenticationInfo中的代码;
     * )
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
    
        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));
    
        return hashedCredentialsMatcher;
    }
    
    点赞 评论 复制链接分享

相关推荐