zoukankan      html  css  js  c++  java
  • Shiro通过注解配置授权

    接着上一篇文章的基础之上:

    pom中添加一个切面编程aop的依赖:

            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.9</version>
            </dependency>    

    然后在spring-mvc.xml文件中开启aop并做相关配置:

    <!--//开启aop-->
        <aop:config proxy-target-class="true"/>
        <!--创建一个保证shiro内部Lifecycle正常执行的对象-->
        <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
        <!--创建一个shiro授权生效的对象-->
        <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
            <property name="securityManager" ref="securityManager"/>
        </bean>

    接着在controller中添加:

    @RequiresRoles("admin")//这个注解的含义是:必须具备指定角色才可以访问这个链接,执行这个方法
        @RequestMapping(value = "/testRole",method = RequestMethod.GET)
        @ResponseBody
        public String testRole(){
            return "test Role success";
        }
    
        @RequiresRoles("admin1")//这个注解的含义是:必须具备指定角色才可以访问这个链接,执行这个方法
        @RequestMapping(value = "/testRole1",method = RequestMethod.GET)
        @ResponseBody
        public String testRole1(){
            return "test Role success";

    然后运行:

    先登录:

    登录成功后访问url:

    访问成功,说明具备角色。

    接着访问另一个url:/testRole1

    报错500,

    Subject does not have role [admin1]

    说明controller中的注解已经生效。

    还有另一种注解:指定具有相应权限才可访问

    @RequiresPermissions({"login","user:select"})//这个注解的含义是:必须具备指定权限才可以访问这个链接,执行这个方法
        @RequestMapping(value = "/testPermission",method = RequestMethod.GET)
        @ResponseBody
        public String testPermission(){
            return "test Permission success";
        }

    这里在上一篇博客的基础之上,还需要修改一下自定义Realm中的授权内容与getPermissionsByUserName方法,修改后的内容如下:

    @Component
    public class CustomRealm extends AuthorizingRealm {
    
        @Autowired
        private UserDao userDao;
    
    
    
        //授权
        protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            //1.通过主体传过来的认证信息中去获取用户名
            String userName = (String) principalCollection.getPrimaryPrincipal();
            //实际开发时这里从数据库或者缓存中获取角色数据
            Set<String> roles = getRolesByUserName(userName);
    
            Set<String> permissions = getPermissionsByUserName(userName);
            //将取来的角色数据与权限数据返回
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    
            //设置权限
            simpleAuthorizationInfo.setStringPermissions(permissions);
            //设置角色
            simpleAuthorizationInfo.setRoles(roles);
    
            return simpleAuthorizationInfo;
        }
    
        /**
         * 根据用户名获取权限信息
         * @return
         */
        private Set<String> getPermissionsByUserName(String userName) {
            List<String> list = userDao.queryPermissionsByUserName(userName);
            Set<String> sets= new HashSet<>(list);
            return sets;
        }
    
        /**
         * 根据账号取角色信息
         * @param userName
         * @return
         */
        private Set<String> getRolesByUserName(String userName) {
            List<String> list = userDao.queryRolesByUserName(userName);
            Set<String> sets = new HashSet<>(list);
            return sets;
        }
    
        //认证
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
    
            //1.通过主体传过来的认证信息中去获取用户名
            String userName = (String)authenticationToken.getPrincipal();
    
            //2.通过用户名到数据库中获取凭证
            String password = getPasswordByUserName(userName);
            if (password == null){
                return null;
            }
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo
                    (userName,password,"customRealm");
    
            return authenticationInfo;
        }
    
        /**
         * 模拟数据库查询凭证
         * @param userName
         * @return
         */
        private String getPasswordByUserName(String userName){
            //查询数据库
            user user = userDao.getUserByUserName(userName);
            if (user != null){
                return user.getPassword();
            }
            return null;
        }
    
        public static void main(String[] args){
            //因为是模拟数据库操作,
            //数据库中的密码应该都是被MD5加密过的数据
            //所以需要在这里直接打印出加密后的密码
            Md5Hash md5Hash = new Md5Hash("123qwe");
            System.out.println(md5Hash.toString());
        }
    }

    这里在userDao中插入了queryPermissionsByUserName(userName);方法,代码如下:

    @Override
        public List<String> queryPermissionsByUserName(String userName) {
            String sql = "select r.permission from roles_permissions r,user_roles u where u.role_name = r.role_name and u.username = ?";
    
            List<String> permissions = jdbcTemplate.query(sql, new String[]{userName}, new RowMapper<String>() {
                @Override
                public String mapRow(ResultSet resultSet, int i) throws SQLException {
                    return resultSet.getString("permission");
                }
            });
    
            if (CollectionUtils.isEmpty(permissions)){
    
                return null;
            }else {
                for (String s : permissions) {
                    System.out.println(s);
                }
                return permissions;
            }
        }

    运行访问结果如下:

    PS:这里一定要注意数据的设置与返回,也就自定义Realm中的:

         //实际开发时这里从数据库或者缓存中获取角色数据
            Set<String> roles = getRolesByUserName(userName);
    
            Set<String> permissions = getPermissionsByUserName(userName);
            //将取来的角色数据与权限数据返回
            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
    
            //设置权限
            simpleAuthorizationInfo.setStringPermissions(permissions);
            //设置角色
            simpleAuthorizationInfo.setRoles(roles);
    
            return simpleAuthorizationInfo;

    这部分代码,之前因为马虎,

         //设置权限
            simpleAuthorizationInfo.setStringPermissions(permissions);
    忘记塞这个步骤中的
    permissions了,导致疯狂500错误:org.apache.shiro.authz.UnauthorizedException: Subject does not have permission
  • 相关阅读:
    (双指针 二分) leetcode 167. Two Sum II
    (双指针) leetcode 485. Max Consecutive Ones
    (双指针) leetcode 27. Remove Element
    (String) leetcode 67. Add Binary
    (数组) leetcode 66. Plus One
    (N叉树 BFS) leetcode429. N-ary Tree Level Order Traversal
    (N叉树 递归) leetcode 590. N-ary Tree Postorder Traversal
    (N叉树 递归) leetcode589. N-ary Tree Preorder Traversal
    (N叉树 DFS 递归 BFS) leetcode 559. Maximum Depth of N-ary Tree
    (BST 递归) leetcode98. Validate Binary Search Tree
  • 原文地址:https://www.cnblogs.com/xk920/p/10825706.html
Copyright © 2011-2022 走看看