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

来源:互联网 发布:电动车定位软件多少钱 编辑:程序博客网 时间:2024/06/04 18:02

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

//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,view system:user:* 否 system:user:* system:user:update 是 system:user system:user:update 是 system:user:upadate,view system:user 否
0 0
原创粉丝点击