shiro权限标示符

1.shiro权限管理

在实现shiro权限时,一般是继承AuthorizingRealm时,认证方法:
doGetAuthenticationInfo(AuthenticationToken token)
与授权方法:
doGetAuthorizationInfo(PrincipalCollection principals)
其中在授权方法中可以在AuthorizationInfo中添加权限标识符
addStringPermissions(Collection<String> permissions)
与角色信息等.
那么通过查看源码可以得到,指定的权限标识符默认是使用
org.apache.shiro.authz.permission.WildcardPermissionResolver去解析创建成Permission
在鉴权的过程中去进行权限认证的.
public class WildcardPermissionResolver implements PermissionResolver {

    public Permission resolvePermission(String permissionString) {
        return new WildcardPermission(permissionString);
    }
}
也就是在默认情况下,我们的权限标识符是被WildcardPermission来实现解析认证的.

2.shiro默认权限认证方法实现

在查看WildcardPermission源码中可以发现有3个标示符
public class WildcardPermission implements Permission, Serializable {
    //权限通配符
    protected static final String WILDCARD_TOKEN = "*";
    //权限分区符
    protected static final String PART_DIVIDER_TOKEN = ":";
    //权限子分区符
    protected static final String SUBPART_DIVIDER_TOKEN = ",";
    //是否区分大小写
    protected static final boolean DEFAULT_CASE_SENSITIVE = false;
    //将字符串权限解析到这里,List部分是使用 ':'分隔出来的,Set<String> 是','号分隔
    //的部分,例如: system:user:update,delete 
    //最终解析的结果是[[system], [user], [update, delete]]
    private List<Set<String>> parts;
    public boolean implies(Permission p) {
        if (!(p instanceof WildcardPermission)) {
            return false;
        }
        WildcardPermission wp = (WildcardPermission) p;
        List<Set<String>> otherParts = wp.getParts();
        int i = 0;
        for (Set<String> otherPart : otherParts) {
            if (getParts().size() - 1 < i) {
                return true;
            } else {
                Set<String> part = getParts().get(i);
                if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                    return false;
                }
                i++;
            }
        }
        for (; i < getParts().size(); i++) {
            Set<String> part = getParts().get(i);
            if (!part.contains(WILDCARD_TOKEN)) {
                return false;
            }
        }
        return true;
    }
}
权限认证方法中可以看到,逐级比较':'分区的内容.
1.如果持有权限分区长度大于需要的权限分区长度且短分区能一一相匹配时,除非除非长分区后面
都是*这种统配符否则认证不通过.
例如:
用户用户有权限--> system:user:update
目标需要权限 -->  system:user
结果是认证失败. 如果用户的权限是-->system:user:* 则可以通过
2.如果持有权限的分区长度小于需要的权限分区长度且短分区能一一相匹配时,直接认证通过.
例如:
用户用户有权限--> system:user
目标需要权限 -->  system:user:update
结果是认证成功.如果用户权限是-->system:user:* 则一样能认证成功
3.如果包含子分区,则必须子分区必须被拥有子分区权限全部包含才可认证通过.
例如:
用户拥有权限 --> system:user:update,delete,add
目标需要权限 --> system:user:update
结果是认证成功,反之则不行.
用户拥有权限 --> system:user,dict,config:update
目标需要权限 --> system:user:delete
结果是认证成功


此外,如果想要定义自己的Permission 可以通过实现
org.apache.shiro.authz.permission.PermissionResolver接口中创建自定义的Permssion实现类
并设置到realm中即可

猜你喜欢

转载自blog.csdn.net/m0_38043362/article/details/78672440