拓展shiro的字符串权限匹配

shiro框架中,可以使用字符串匹配权限。
比如user:query匹配查询用户的权限。
user:*可以匹配user:query,user:delete等。
然而,却不可以匹配user:id:query。即不可以跨级(分隔符:将字符串分为多个级)。
这里提供了一个可以多级匹配的实现。

MyRealm.java

public class MyRealm extends AuthorizingRealm {
    public MyRealm() {
        this(null, null);
    }

    public MyRealm(CacheManager cacheManager) {
        this(cacheManager, null);
    }

    public MyRealm(CredentialsMatcher matcher) {
        this(null, matcher);
    }

    public MyRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
        super(cacheManager,matcher);
        //shiro默认的权限字符串匹配方式是通过WildcardPermissionResolver和WildcardPermission方式
        setPermissionResolver(new MyWildcardPermissionResolver());
    }
    /**
     * 获得授权信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
      ...
    }

    @Override
    /**
     * 获得认证信息认证
     */
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 
        throws AuthenticationException {
       ...
    }

}

MyWildcardPermissionResolver.java

public class MyWildcardPermissionResolver implements PermissionResolver{

    @Override
    public Permission resolvePermission(String permissionString) {
        return new MyWildcardPermission(permissionString);
    }
}

MyWildcardPermission.java

/**
 * 拓展shiro的WildcardPermission,增强权限字符串匹配功能,增加使用**匹配多级字符串的模式。
 * eg:a:b:c可以匹配a:**
 *    a:b:c:d 可以匹配a:**:d
 *    a:b:c:d 可以匹配a:**
 *    a:b:c:d 可以匹配a:*:**
 *    a:b:c:d 可以匹配a:**:*
 *    a:b:c:d:e可以匹配a:**:d:**
 *    a:b:c:d可以匹配a:**:b:c:d
 *    
 * */
public class MyWildcardPermission extends WildcardPermission{
    private static final long serialVersionUID = 1L;
    protected static final String MY_WILDCARD_TOKEN = "**";
    protected MyWildcardPermission() {
        super();
    }

    public MyWildcardPermission(String wildcardString) {
        this(wildcardString, DEFAULT_CASE_SENSITIVE);
    }

    public MyWildcardPermission(String wildcardString, boolean caseSensitive) {
        setParts(wildcardString, caseSensitive);
    }
    public boolean implies(Permission p) {
        // By default only supports comparisons with other WildcardPermissions
        if (!(p instanceof MyWildcardPermission)) {
            return false;
        }

        MyWildcardPermission wp = (MyWildcardPermission) p;

        List<Set<String>> otherParts = wp.getParts();//执行需要的权限集合

        int partIndex = 0;
        int otherIndex = 0;
        List<Set<String>> parts = getParts();//拥有的权限
        if(!otherParts.isEmpty()){
            while(true){
                if(partIndex >= parts.size()){//如果 parts用完了,就返回true
                    return true;
                }
                if(otherIndex>=otherParts.size()){
                //如果otherParts用完了,就跳出循环,判断parts之后的部分。
                    break;
                }
                Set<String> otherPart = otherParts.get(otherIndex);//当前otherPart
                Set<String> part = parts.get(partIndex);//当前part
//如果part既不是通配符*,又不全部包含otherPart,就判断是否包含**
                    if(part.contains(MY_WILDCARD_TOKEN)){
                        partIndex = partIndex+1;//如果**后面没有part了,就说明parts用完了,返回true
                        if(partIndex >= parts.size()){
                            return true;
                        }
                        part = parts.get(partIndex);//取**后面的part
//遍历otherParts当前与之后的otherPart,与**后面的part匹配
                            otherPart = otherParts.get(otherIndex);
                            if(part.containsAll(otherPart)){//匹配上了就跳出for循环,继续匹配
                                break;
                            }
                        }
                        if(otherIndex==otherParts.size()){
                        //如果otherParts用完了,就跳出循环,判断parts之后的部分。
                            break;
                        }
                    }else{
                        return false;
                    }
                }
                partIndex++;
                otherIndex++;
            }
        }

        // If this permission has more parts than the other parts, 
        //only imply it if all of the other parts are wildcards
        for (; partIndex < getParts().size(); partIndex++) {
            Set<String> part = getParts().get(partIndex);
            if (!part.contains(WILDCARD_TOKEN) && !part.contains(MY_WILDCARD_TOKEN)) {
                return false;
            }
        }

        return true;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值