zoukankan      html  css  js  c++  java
  • (转)shiro权限框架详解05-shiro授权

    http://blog.csdn.net/facekbook/article/details/54910606

    本文介绍

    • 授权流程
    • 授权方式
    • 授权测试
    • 自定义授权realm

    授权流程

    开始构造SecurityManager环境subject.isPermitted()授权securityManager.isPermitted()执行授权Authorizer执行授权Realm根据身份获取资源权限信息结束

    授权方式

    Shiro支持三种方式的授权:

    • 编程式:通过写if/else授权代码块完成。
    Subject subject = SecurityUtils.getSubject();
    if(subject.hasRole("admin")){
    //有权限
    }else{
    //没有权限
    }
    • 注解式:通过在执行的Java方法上放置相应的注解完成。
    @RequiresRole("admin")
    public void hell(){
    //有权限
    }
    • JSP标签:在Jsp页面通过相应的标签完成:
    <shiro:hasRole name="admin">
    <!--有权限-->
    </shiro:hasRole>

    授权测试

    创建ini配置文件

    在classpath路径下创建shiro-permission.ini文件,内容如下:

    [users]
    #用户zhangsan的密码是123,此用户具有role1和role2两个角色
    zhangsan=123,role1,role2
    lisi=123,role2
    
    [roles]
    #角色role1对资源user拥有create、update权限
    role1=user:create,user:update
    #角色role2对资源user拥有create、delete权限
    role2=user:create,user.delete
    #角色role3对资源user拥有create权限
    role3=user:create

    在ini文件中用户、角色、权限的配置规则是: 用户名=密码,角色1,角色2 、角色=权限1,权限2。首先根据用户找角色,再根据角色找权限,角色是权限集合。

    权限字符串规则

    权限字符串的规则是:”资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,”:”是资源/操作/实例的分割符,权限字符串也可以使用*通配符。 
    例子: 
    用户创建权限:user:create或user:create:* 
    用户修改实例001的权限:user:update:001 
    用户实例001的所有权限:user:*:001

    测试代码

        @Test
        public void testPermission() {
            // 构建SecurityManager工厂,IniSecurityManagerFactory可以从ini文件中初始化SecurityManager环境
            Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");
            // 通过工厂创建SecurityManager
            SecurityManager securityManager = factory.getInstance();
            // 将SecurityManager设置到运行环境中
            SecurityUtils.setSecurityManager(securityManager);
            //创建一个Subject实例,该实例认证需要使用上面创建的SecurityManager
            Subject subject = SecurityUtils.getSubject();
            //创建token令牌,账号和密码是ini文件中配置的
            //AuthenticationToken token = new UsernamePasswordToken("zhangsan", "123");//账号密码正确token 角色是 role1,role2
            AuthenticationToken token = new UsernamePasswordToken("lisi", "123");//lisi账号的token 角色是role3
            /**
             * role1=user:create,user:update
               role2=user:create,user.delete
               role3=user:create
             */
            try {
                //用户登录
                subject.login(token);
            } catch (AuthenticationException e) {
                e.printStackTrace();
            }
            //用户认证状态
            Boolean isAuthenticated = subject.isAuthenticated();
            System.out.println("用户认证状态:"+isAuthenticated);//输出true
    
    
            //用户授权检测
            //是否拥有一个角色
            System.out.println("是否拥有一个角色:"+subject.hasRole("role1"));
            //是否拥有多个角色
            System.out.println("是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));
    
            //检测权限
            try {
                subject.checkPermission("user:create");
            } catch (AuthorizationException e) {
                e.printStackTrace();
            }
            try {
                subject.checkPermissions("user:create","user.delete");
            } catch (AuthorizationException e) {
                e.printStackTrace();
            }
        }

    基于角色的授权

    //是否拥有一个角色
    System.out.println("是否拥有一个角色:"+subject.hasRole("role1"));
    //是否拥有多个角色
    System.out.println("是否拥有多个角色:"+subject.hasAllRoles(Arrays.asList("role1","role2")));

    对应的check方法:

    subject.checkRole("role1");
    subject.checkRoles(Arrays.asList("role1","role2"));

    上边check方法如果授权失败则抛出异常:

    org.apache.shiro.authz.UnauthorizedException: Subject does not have role [.....]

    基于资源授权

    System.out.println("是否拥有某个权限:"+subject.isPermitted("user:create"));
    System.out.println("是否拥有多个权限:"+subject.isPermittedAll("user:create","user.delete"));

    对应的check方法:

    subject.checkPermission("user:create");
    subject.checkPermissions("user:create","user.delete");

    上边check方法如果授权失败则抛出异常:

    org.apache.shiro.authz.UnauthorizedException: Subject does not have permission [....]

    自定义realm

    shiro认证那篇博客中编写的自定义realm类中有一个doGetAuthorizationInfo 方法,此方法需要完成:根据用户身份信息从数据库查询权限字符串,由shiro进行授权。

    realm代码

    /**
    * 授权方法
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            //后去身份信息,这个字段就是前面的username
        String username = (String)principals.getPrimaryPrincipal();
    
        //模拟通过身份信息获取所有权限
        List<String> permissions = new ArrayList<>();
        permissions.add("user:create");
        permissions.add("user:delete");
    
        //将权限信息封装到AuthorizationInfo中,并返回
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.addStringPermissions(permissions);
        return authorizationInfo;
    }

    shiro-realm.ini文件

    需要使用这个配置文件。

    测试代码

    同上边的授权测试代码,注意修改ini地址为shiro-realm.ini。

    授权执行流程

    1、 执行subject.isPermitted(“user:create”) 
    2、 securityManager通过ModularRealmAuthorizer进行授权 
    3、 ModularRealmAuthorizer调用realm获取权限信息 
    4、 ModularRealmAuthorizer再通过permissionResolver解析权限字符串,校验是否匹配

    该文章涉及的代码

    代码地址

  • 相关阅读:
    bean扫描的问题
    软件测试综合实训提问环节
    cephfs
    Django ORM数据增删改查接口
    ceph使用问题积累
    ceph删除pool
    Windows容器使用阿里云NAS SMB文件系统做持久化存储目录
    ceph安装( nautilus 版本 )
    K8S使用cephcsi持久化存储之CephFS
    服务器监控jmeter之 jp@gc PerfMon Metrics Collector
  • 原文地址:https://www.cnblogs.com/telwanggs/p/7118129.html
Copyright © 2011-2022 走看看