shiro字符串权限解析器内部分析

首先在源码中找到了将权限字符串拆分的方法,如下:

//wildcardString 权限字符串
//caseSensitive 字符串大小写转换标记
protected void setParts(String wildcardString, boolean caseSensitive) {
        //判断权限字符串不为空
        if (wildcardString == null || wildcardString.trim().length() == 0) {
            throw new IllegalArgumentException("Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.");
        }

        wildcardString = wildcardString.trim();
        //按照“:”切割字符串(PART_DIVIDER_TOKEN 为 ‘:’)
        List<String> parts = CollectionUtils.asList(wildcardString.split(PART_DIVIDER_TOKEN));

        this.parts = new ArrayList<Set<String>>();
        //循环把切割后的字符串按照‘,’再次切割,然后放入权限集合中(SUBPART_DIVIDER_TOKEN 为 ‘,’)
        for (String part : parts) {
            Set<String> subparts = CollectionUtils.asSet(part.split(SUBPART_DIVIDER_TOKEN));
            if (!caseSensitive) {
                subparts = lowercase(subparts);
            }
            if (subparts.isEmpty()) {
                throw new IllegalArgumentException("Wildcard string cannot contain parts with only dividers. Make sure permission strings are properly formatted.");
            }
            this.parts.add(subparts);
        }

        if (this.parts.isEmpty()) {
            throw new IllegalArgumentException("Wildcard string cannot contain only dividers. Make sure permission strings are properly formatted.");
        }
    }

到此,shiro将权限字符串已经全部解析为单个权限字段如:
system:user,shopping:update,view -> (system) ((shopping)(user)) ((update)(view))
那么通配符在哪里匹配的呢?

下面这个方法是实现Permission接口的方法,检查是否拥有某个权限:

    public boolean implies(Permission p) {
        // By default only supports comparisons with other WildcardPermissions
        if (!(p instanceof WildcardPermission)) {
            return false;
        }

        //此处主要区分wp为外部传进来请求判断是否拥有的权限
        WildcardPermission wp = (WildcardPermission) p;

        List<Set<String>> otherParts = wp.getParts();

        int i = 0;
        for (Set<String> otherPart : otherParts) {
            // If this permission has less parts than the other permission, everything after the number of parts contained
            // in this permission is automatically implied, so return true
            if (getParts().size() - 1 < i) {
                //如果循环结束任然没有返回错误,那就是拥有这个权限,返回true
                return true;
            } else {
                //part为系统内本身的权限列表
                Set<String> part = getParts().get(i);
                //如果内部不包含‘*’且没有这个权限的话,就认为没有权限
                if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                    return false;
                }
                i++;
            }
        }

        // If this permission has more parts than the other parts, only imply it if all of the other parts are wildcards
        //这个for主要判断在内部权限字符串比外部传入的权限字符串长的情况,为防止user匹配到user:update(这样的匹配,假设只有update权限,如果有一个add操作,用user去匹配的话,匹配到update权限,通过的话,则代表add权限也拥有了,所以除非内部权限多出来的部分是*,否则都为失败)
        for (; i < getParts().size(); i++) {
            Set<String> part = getParts().get(i);
            if (!part.contains(WILDCARD_TOKEN)) {
                return false;
            }
        }

        return true;
    }

到此,我们知道了:

内部权限外部权限可否匹配
system:user:upadate,viewsystem:user:*
system:user:*system:user:update
system:usersystem:user:update
system:user:upadate,viewsystem:user
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值