shiro权限比对的一些坑

2 篇文章 0 订阅
1 篇文章 0 订阅

  最近在做shiro权限控制的时候,搭建完了环境给同事使用,同事使用的时候发现了一个bug,让我看看,bug是这样的,

       在freemarke中使用shiro标签,<@shiro.hasPermission name="sys:user:1111"></@shiro.hasPermission>发现标签不起作用,而这个权限在数据库是没有配置,查询出来的授权管理的权限列表里面也没有此权限,如果改为<@shiro.hasPermission name="sys:user:1113222"></@shiro.hasPermission>也是一样的,

据此我排查了以下几个问题:

1、shiro标签是引用进去的,可以使用,只是比对权限出现了问题,

2、换了其他权限控制是正常的。

最后没办法、只能跟踪源码去查看比对情况了。下面这个方法是最后比对权限的那个方法,编译后的源码,

这个方法在org.apache.shiro.authz.permission.WildcardPermission这个类中,实现了org.apache.shiro.authz.Permission接口,

//传进来的参数是要比对的权限、比如上面的sys:user:1111这个权限,

public boolean implies(Permission p) {

  //判断这个权限是否是WildcardPermission,否则否,这个没什么问题,

    if(!(p instanceof WildcardPermission)) {
      return false;
    } else {
      WildcardPermission wp = (WildcardPermission)p;
      List<Set<String>> otherParts = wp.getParts();
      int i = 0;
     //这个地方开始迭代传进来的权限 比如sys:user:1111会变成[[sys],[user],[1111]]

      for(Iterator i$ = otherParts.iterator(); i$.hasNext(); ++i) {

        //此时的权限控制失效的问题就出在这个地方 从0开始比对,比如比对到1111的时候,此时i=2  但是系统配的权限配的是          //sys:user,此时的this.getParts().size=2   再-1就等于1 <2 ,返回了true,此时才反应过来shiro的权限比对规则。

        Set<String> otherPart = (Set)i$.next();
        if(this.getParts().size() - 1 < i) {
          return true;
        }

        //判断系统配的权限是否包含通配符*,并且是否包含要判断的权限
        Set<String> part = (Set)this.getParts().get(i);
        if(!part.contains("*") && !part.containsAll(otherPart)) {
          return false;
        }
      }

        //如果要比对的两个权限,系统配置的,还有自己传进去要比对的两者,因为都转化为了list<set>结构,

//如果系统的当前权限list.size()小于了迭代次数i,并且不包含通配符*的时候就返回 false;

      while(i < this.getParts().size()) {
        Set<String> part = (Set)this.getParts().get(i);
        if(!part.contains("*")) {
          return false;
        }
        ++i;
      }
      return true;
    }

  }


此时bug出现的原因就是:同事配置了一个sys:user权限,但是他判断sys:user:1111的权限的时候,就返回了true,默认sys:user权限里面包含了sys:user:1111, 跟sys:user:*里面包含sys:user:1111一样的道理。

总结下shiro权限配置规则以及权限比对规则:shiro里面使用:作为权限分隔符,根据:作为正则来分隔并且转化为list<set>,

一般用如下配置:一级模块名(如用户、系统、菜单):二级子模块:操作标识符,  依次往下类推

如果要比对的两者权限中,一级模块名相同就比对二级,二级相同就比对三级, 如果包含有通配符*则有以下规则;

比如:sys:user:*(或者sys:user)中就包含了 sys:user:create,update,delete三个操作用户的权限

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值