Shiro介绍(五):WildcardPermission解读

本文介绍了Shiro中的WildcardPermission在权限控制中的应用,包括如何使用通配符进行权限授权和校验。详细解析了`user:create,update`等权限字符串的含义,并通过例子展示了不同授权与校验组合的结果,强调了在权限分配时可模糊,校验时需明确的原则。" 132802473,442749,自定义OBS全局热键实现详解,"['OBS', '快捷键', '自定义热键']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于Role-Permission两级权限体系,大多数情况下,我们都是直接使用Shiro提供的WildcardPermission来实现细粒度的权限控制。

Shiro为我们定义了一个抽象的权限描述字串:
【资源】:【操作】:【实例】

例如:”user:create,update”,”user:delete:100110”,等等。

Shiro的通配符权限,可以这样使用【以下描述中『授权』指分配给当前用户的权限,而『校验』指在注解或JSP标签中写的权限】:

  1. 授权(user),校验(user),结果(通过)
  2. 授权(user),校验(user:create),结果(通过)
  3. 授权(user:create),校验(user:update),结果(不通过)
  4. 授权(user:create),校验(user:create,update),结果(不通过)
  5. 授权(user:create,update),校验(user:update),结果(通过)
  6. 授权(user:create),校验(user:*),结果(不通过)
  7. 授权(user:*),校验(user:create),结果(通过)
  8. 。。。

那么,这个支持通配符Permission的内部逻辑又是如何实现的,是一个比较有意思的话题。
来看代码:

    public boolean implies(Permission p) {
        // 只支持与另一个WildcardPermission作比较
        if (!(p instanceof WildcardPermission)) {
            return false;
        }

        WildcardPermission wp = (WildcardPermission) p;

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

        int i = 0;
        for (Set<String> otherPart : otherParts) {
            // 如果当前permission长度比other permission短,校验通过
            // 参见示例(2)
            if (getParts().size() - 1 < i) {
                return true;
            } else {
                Set<String> part = getParts().get(i);
                //如果当前permission的当前Part不是*,
                //且又不能包住other permission的当前Part,则校验不通过
                //否则继续,直到处理完当前permission的所有节
                // 参见示例(3)(4)
                if (!part.contains(WILDCARD_TOKEN) && !part.containsAll(otherPart)) {
                    return false;
                }
                i++;
            }
        }

        // 上面逻辑没有返回false,开始检查当前permission多出来的part
        // 如果多出来的part只要有一个不为*,则不通过。
        // 参见示例(7)
        for (; i < getParts().size(); i++) {
            Set<String> part = getParts().get(i);
            if (!part.contains(WILDCARD_TOKEN)) {
                return false;
            }
        }

        return true;
    }

代码加了注释,从这个实现逻辑来看,尤其是那一句!part.containsAll(otherPart),我们就明白了缺省情况下,permission如果用逗号分隔多个时,是『与』的关系,而非『或』。

这时,我们来回忆一下在注解中,有这样的写法@RequiresPermissions(value={"channel:edit","channel:create"},logical=Logical.OR),说明Shiro还是在帮我们处理多个权限共存时,AND或OR的问题。所以,这里不能用@RequiresPermissions("channel:edit,create")

也就是说,我们常说的一个原则『分配权限时可以模糊,但校验时一定要明确』,参见示例7(正例),6(反例)。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值