Spring Boot +Shiro 思路和备注

来源:互联网 发布:深圳外贸优化 编辑:程序博客网 时间:2024/06/03 13:01

思路

在使用shiro的时候,我们需要将ShiroConfiguration注入到spring中和实现MyShiroRealm
在ShiroConfiguration中 主要作用是
权限过滤规则
管理器注入(缓存、记住我等管理器)
密码匹配器
在使用密码匹配时,我们需要告诉shiro使用什么规则(MD5)

  @Bean    public HashedCredentialsMatcher hashedCredentialsMatcher(){//        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();        HashedCredentialsMatcher hashedCredentialsMatcher = new RetryLimitHashedCredentialsMatcher(ehCacheManager());        hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;        hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5(""));        return hashedCredentialsMatcher;    }

在Realm中
我们把正确的账号密码告诉shiro,shiro就会使用我们之前确定的规则进行匹配。

   //明文: 若存在,将此用户存放到登录认证info中,无需自己做密码对比,Shiro会为我们进行密码对比校验      SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(           userInfo, //用户名           userInfo.getPassword(), //密码             getName()  //realm name      );

第一个参数是放在subject中,可以在其他功能里使用。

Subject subject = SecurityUtils.getSubject();//当前会话        if( subject.isAuthenticated()){            UserInfo userInfo=(UserInfo) subject.getPrincipal();            setFieldValByName("editor",  userInfo.getUserName(), metaObject);        }

第二个参数是正确的密码,在我们new SimpleAuthenticationInfo时 会调用HashedCredentialsMatcher里的doCredentialsMatch方法。在我们传过来的密码 会自动帮我们MD5加密后与我们查询到的正确密码匹配。
第三个参数。是realm的名字。

在使用注解时,@RequiresRoles 是否拥有角色。
就是在MyShiroRealm中重写的doGetAuthorizationInfo里设置的角色。

        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();        UserInfo userInfo  = (UserInfo)principals.getPrimaryPrincipal();          for(SysRole role:userInfo.getRoleList()){            authorizationInfo.addRole(role.getRole());//添加角色            SysRole sysRole = sysRoleService.selectRoleByIdWithPermission(role.getId());//获取角色            for(SysPermission p:sysRole.getPermissions()){                authorizationInfo.addStringPermission(p.getPermission());//添加权限            }        }//属于user角色@RequiresRoles("user")//必须同时属于user和admin角色@RequiresRoles({"user","admin"})//属于user或者admin之一;修改logical为OR 即可@RequiresRoles(value={"user","admin"},logical=Logical.OR)使用注解 

@RequiresPermissions(“userInfo:del”)是否拥有权限

//符合index:hello权限要求@RequiresPermissions("index:hello")//必须同时复核index:hello和index:world权限要求@RequiresPermissions({"index:hello","index:world"})//符合index:hello或index:world权限要求即可@RequiresPermissions(value={"index:hello","index:world"},logical=Logical.OR)

附上一个连接注解详细连接http://blog.csdn.net/w_stronger/article/details/73109248

在实现AuthorizingRealm时,
我们需要doGetAuthenticationInfo做认证和doGetAuthorizationInfo权限信息
这两个接口实现就可以。
在我们登录的时候 首先会跑doGetAuthenticationInfo这个方法。
做完密码匹配后 会将结果放到request中 存放一个参数shiroLoginFailure。
如果失败后我们通过判断异常就可以知道是什么登录错误

    // 登录提交地址和applicationontext-shiro.xml配置的loginurl一致。 (配置文件方式的说法)        @RequestMapping(value="/login",method=RequestMethod.POST)        public String login(HttpServletRequest request, Map<String, Object> map) throws Exception {            System.out.println("HomeController.login()");            // 登录失败从request中获取shiro处理的异常信息。            // shiroLoginFailure:就是shiro异常类的全类名.            String exception = (String) request.getAttribute("shiroLoginFailure");            System.out.println("exception=" + exception);            String msg = "";            if (exception != null) {                if (UnknownAccountException.class.getName().equals(exception)) {                    System.out.println("UnknownAccountException -- > 账号不存在:");                    msg = "UnknownAccountException -- > 账号不存在:";                } else if (IncorrectCredentialsException.class.getName().equals(exception)) {                    System.out.println("IncorrectCredentialsException -- > 密码不正确:");                    msg = "IncorrectCredentialsException -- > 密码不正确:";                } else if ("kaptchaValidateFailed".equals(exception)) {                    System.out.println("kaptchaValidateFailed -- > 验证码错误");                    msg = "kaptchaValidateFailed -- > 验证码错误";                }else if (ExcessiveAttemptsException.class.getName().equals(exception)) {                    System.out.println("ExcessiveAttemptsException -- > 登录失败次数过多:");                    msg = "ExcessiveAttemptsException -- > 登录失败次数过多:";                }   else {                    msg = "else >> "+exception;                    System.out.println("else -- >" + exception);                }            }            map.put("msg", msg);            // 此方法不处理登录成功,由shiro进行处理.            return "/login";        }

需要完整代码demo的可以留下邮箱 或者发邮件到736187475@qq.com索取项目demo代码

原创粉丝点击