我们在 Spring Security 中遇到了意外缺少按位权限检查的问题。我们想确认这是否是预期的行为,如果是,历史是什么和/或这样做的理由。
我们正在使用 grails 插件 spring-security-acl-1.1.1,它使用 spring-security-acl 3.0.7.RELEASE。
我们正在尝试的一个提炼场景涉及一个具有 ACL 的对象,这样 aclUtilService.readAcl(obj) 返回授予角色:
PrincipalSid[sampleuser]; permission: BasePermission[...........................A....=16]
GrantedAuthoritySid[ROLE_RWD]; permission: CumulativePermission[............................D.WR=11]
GrantedAuthoritySid[ROLE_RW]; permission: CumulativePermission[..............................WR=3]
GrantedAuthoritySid[ROLE_R]; permission: BasePermission[...............................R=1]
随后,我们希望检查单个权限,如 WRITE 并让它返回 true。但是,这似乎不受支持。例如,对于具有上述对象上定义的所有角色的用户,执行:
READ?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.READ)}
WRITE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.WRITE)}
DELETE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, BasePermission.DELETE)}
READ-WRITE?: ${aclUtilService.hasPermission(springSecurityService.authentication, obj, new BasePermission(BasePermission.READ.getMask() | BasePermission.WRITE.getMask()))}
返回输出:
READ?: true
WRITE?: false
DELETE?: false
READ-WRITE?: true
而我们希望所有这些都返回 true。查看源代码后,我们可以看到最终在 AclImpl 中检查了权限,其中包含以下行
if ((ace.getPermission().getMask() == p.getMask()) && ace.getSid().equals(sid)) {
这解释了为什么只有确切的掩码匹配。
仅更改这一行有点涉及,我们发现在 spring-security-acl 3.1 中,此代码被重构以允许定义权限授予策略 - https://jira.spring.io/browse/SEC-1166
然而,默认的授权策略仍然只检查确切的掩码。所以:
- 为什么默认授予策略不检查按位掩码?如果不应该检查 CumulativePermission 有什么意义?
- 处理按位权限的首选方法是什么,我们是否错误地配置了权限,或者我们应该只寻求实现按位权限检查(在这种情况下,首选的方法是什么)。
感谢您的任何解释或指导。