我正在使用具有域级安全性(ACL)的Spring Security。
我有两个域名公司和书。
class Company {
String name
hasMany = [books: Book]
}
class Book {
String title
belongsTo = [company: Company]
}
我读过一个ACL可以有一个Parent,它从。
继承了它的权限在服务中我会有这样的方法来设置新的图书卡的权限:
@PreAuthorize("hasRole('ROLE_ADMIN') or hasPermission(#book, admin)")
void addPermission(Book book, String username, Permission permission) {
aclUtilService.addPermission(book, username, permission)
}
这样可以正常工作并为新书实例创建权限。我还有一个更新方法,可以在更新本书之前检查权限。
@PreAuthorize("hasPermission(#book, write) or hasPermission(#book, admin)")
Book update(Book book, Map params = [:]) {
book.properties = params
book.save(flush:true)
return book
}
只要用户拥有该书的权限,这就可以正常工作。但是,我希望将父对象(公司)的权限用户继承到该书。当用户获得我想要的公司许可时,它也允许所有公司的书籍。
我在AclImp中看到有一个方法setParent()
。这样做有用:
AclImpl acl = aclUtilService.readAcl(book)
acl.setParent(aclUtilService.readAcl(book.company))
aclService.updateAcl(acl)
使用上面的代码将在数据库中设置book的parent。
如何在Spring Security ACL中使用继承?
答案 0 :(得分:2)
您可以这样做,而不是使用父ACL:
@PreAuthorize("hasPermission(#book.company, write) or hasPermission(#book.company, admin)")
Book update(Book book, Map params = [:]) {
book.properties = params
book.save(flush:true)
return book
}
如果您希望从父ACL继承,请确保将子AclObjectIdentity
entriesInheriting
设置为true
,例如使用createAcl
方法下面:
void createAcl(Class clazz, Long id, String sid, AclObjectIdentity parent) {
clazz = ProxyUtils.unproxy(clazz)
AclClass aclClass = AclClass.findOrSaveByClassName(clazz.name)
AclSid ownerSid = AclSid.findOrSaveBySidAndPrincipal(sid, true)
AclObjectIdentity oid = findOrCreateObjectIdentity(aclClass, ownerSid, id, parent, true)
}
AclObjectIdentity findOrCreateObjectIdentity(AclClass aclClass, AclSid ownerSid, Long id, AclObjectIdentity parent, boolean entriesInheriting) {
assert aclClass, "aclClass is required"
assert null != id, "id is required"
AclObjectIdentity oid = AclObjectIdentity.findOrCreateByAclClassAndObjectId(aclClass, id)
if (null == oid.id) {
oid.entriesInheriting = entriesInheriting
oid.owner = ownerSid
oid.parent = parent
oid.save(flush: true, failOnError: true)
}
oid
}
如果ACL继承@PreAuthorize("hasPermission(#child, read)")
将返回true,如果当前用户已读取父ACL的