问题描述:最近对权限系统做了一次更新,重新梳理了所有权限并且通过自定义注解配合AOP扫描拦截所有的异常权限请求,但是梳理完成权限后发现页面上的shiro标签和代码中某些地方的subject.isPermitted(key) “理应”返回false的地方返回了true.
处理过程:debuge进入源码一直进到
其中具体参数:
从implies进入WildcardPermission
发现在这里返回了true,此时刻getParts()为crm:sys (角色拥有的多个权限之一) 而 i的长度代表的元素本身为crm:sys:role(目标权限,既需要判断系统里有没有该权限,有就放行)
这时我明白了一切的问题是由于我们命名产生的!(我们命名的结构中希望拥有子权限的人理所应当的拥有父权限,然而shiro的权限判断中认为命名重叠的两个权限中,短名称的权限是级别更高的权限)
说下我们的命名:
我们的命名是按照菜单目录结构而来,一级菜单如: crm:statistic 二级菜单: crm:statistic:source 三级菜单:crm:statistic:source:xxx
我们使用冒号 “:” 其实是shiro权限命名中的关键字符,使用冒号命名的权限会被切割成多个级别放入set<T>中 如: [crm] [statistic] [source]
解决方式:
1.重新命名比如将":"替换为“_”,当然判断效率相对于冒号命名效率肯定下降,因为变成了完全匹配。
2.按照从长到短的方式进行命名,命名难度较大。