zoukankan      html  css  js  c++  java
  • 【Shiro学习之三】权限验证

    Apache shiro:1.6.0

    一、重要组件
    1、Authorizer 的职责是进行授权(访问控制),是 Shiro API 中授权核心的入口点,其提供了相应的角色/权限判断接口,具体协调realm验证权限是在ModularRealmAuthorizer里进行。

    2、PermissionResolver接口用于解析权限字符串到WildcardPermission实例,默认实现WildcardPermissionResolver;RolePermissionResolver接口用于根据角色解析相应的权限集合。

    3、AuthorizationInfo

    public interface AuthorizationInfo extends Serializable { 
        Collection<String> getRoles(); //获取角色字符串信息 
        Collection<String> getStringPermissions(); //获取权限字符串信息 
        Collection<Permission> getObjectPermissions(); //获取 Permission 对象信息 
    } 

    AuthorizationInfo 用于聚合授权信息的,当我们使用AuthorizingRealm 时, 如果身份验证成功, 在进行授权时就通过doGetAuthorizationInfo 方法获取角色/权限信息用于授权验证。
    Shiro提供了一个实现 SimpleAuthorizationInfo,大多数时候使用这个即可

    二、权限验证流程
    1、代码示例
    (1)角色验证

    @Test
        public void testHasRole() {
            login("classpath:shiro-role.ini", "zhang", "123");
            //判断拥有角色:role1
            Assert.assertTrue(subject().hasRole("role1"));
            //判断拥有角色:role1 and role2
            Assert.assertTrue(subject().hasAllRoles(Arrays.asList("role1", "role2")));
            //判断拥有角色:role1 and role2 and !role3
            boolean[] result = subject().hasRoles(Arrays.asList("role1", "role2", "role3"));
            Assert.assertEquals(true, result[0]);
            Assert.assertEquals(true, result[1]);
            Assert.assertEquals(false, result[2]);
        }

    (2)权限验证

    @Test
        public void testIsPermitted() {
            login("classpath:shiro-permission.ini", "zhang", "123");
            //判断拥有权限:user:create
            Assert.assertTrue(subject().isPermitted("user:create"));
            //判断拥有权限:user:update and user:delete
            Assert.assertTrue(subject().isPermittedAll("user:update", "user:delete"));
            //判断没有权限:user:view
            Assert.assertFalse(subject().isPermitted("user:view"));
        }

    2、图示流程

    流程如下: 
    (1)首先调用Subject.isPermitted*/hasRole*接口,其会委托给 SecurityManager,而SecurityManager 接着会委托给 Authorizer; 
    (2)Authorizer 是真正的授权者,如果我们调用如 isPermitted(“user:view”),其首先会通过PermissionResolver 把字符串转换成相应的 Permission 实例; 
    (3)在进行授权之前,其会调用相应的 Realm 获取 Subject 相应的角色/权限用于匹配传入的角色/权限; 
    (4)Authorizer 会判断 Realm 的角色/权限是否和传入的匹配,如果有多个 Realm,会委托给ModularRealmAuthorizer 进行循环判断,如果匹配如 isPermitted*/hasRole*会返回 true,否则返回 false 表示授权失败。 

    3、源码流程分析

    角色验证:

    Subject::hasRole
    -->DelegatingSubject::hasRole
    -->securityManager::hasRole
    -->AuthorizingSecurityManager::hasRole
    -->ModularRealmAuthorizer::hasRole
    在这里会获取所有的realm,调用realm的doGetAuthorizationInfo进行获取权限信息AuthorizationInfo
    -->然后AuthorizationInfo调用getRoles()获取所有角看是否包含指定的角色;
    ModularRealmAuthorizer 进行多 Realm 匹配流程: 
    (1)首先检查相应的Realm是否实现了实现了 Authorizer; 
    (2)如果实现了Authorizer,那么接着调用其相应的isPermitted*/hasRole*接口进行匹配; 
    (3)如果有一个Realm匹配那么将返回true 否则返回 false

    权限验证:

    Subject::isPermitted
    -->DelegatingSubject::isPermitted
    -->securityManager::isPermitted
    -->AuthorizingSecurityManager::isPermitted
    -->ModularRealmAuthorizer::isPermitted
    -->AuthorizingRealm::isPermitted
    首先通过 PermissionResolver 将权限字符串转换成相应的 Permission 实例,默认使用 WildcardPermissionResolver,即转换为通配符的WildcardPermission;
    然后和realm的doGetAuthorizationInfo获取的权限信息AuthorizationInfo,获得所有权限集合,然后循环比对。
  • 相关阅读:
    基础安全术语科普(四)——RFID
    基础安全术语科普(三)——RAT
    基础安全术语科普(二)——反病毒软件工作原理
    java中的变量
    递归调用
    一个男人关心的东西 决定了他的层次
    安装环境时,请大家不要选择PHP5.3.6
    WordPress URL Rewrite | WP URL 重写组件
    如何在ASP.NET网页间传递数据
    Oracle中的for和while循环
  • 原文地址:https://www.cnblogs.com/cac2020/p/13820696.html
Copyright © 2011-2022 走看看