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
  • 相关阅读:
    uCOS的软件定时器、uCOS时钟节拍和滴答定时器的关系
    学习ucosii要用到的几本书
    freertos知识点笔记——队列、二值信号量、计数信号量
    《嵌入式软件设计基础——基于ARM Cortex—M3》读书笔记
    大小端测试C实现
    static 的三个作用
    基于IAR6或者IAR7建立STM32开发工程(通过实际测试,使用IAR6.30.4)
    STM32中stm32f0xx_flash.icf文件的作用详解!(不错的!)
    CRC点滴
    int *a[] 与(int *)a【5】的区别
  • 原文地址:https://www.cnblogs.com/xk920/p/10825706.html
Copyright © 2011-2022 走看看