shiro权限标示符

来源:互联网 发布:大数据可视化 tableu 编辑:程序博客网 时间:2024/05/29 16:41

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中即可
原创粉丝点击