我们正在开发一个应用程序(使用Grails Spring Security(以前称为Acegi)),其中我们将拥有数千个用户,这些用户跨越10-15个谨慎的用户类型。在当前系统中,每个用户类型等同于“组”,并且特定角色和权限与组相关联。用户从组中获得所有“角色”。
例如,我们可能有两个用户组:
CLOWN:roles = ride_clown_car,toot_horn,receive_applause ACROBAT:roles = do_flip,walk_tightrope,receive_applause
我们有三个用户,一个分配给CLOWN组,一个分配给ACROBAT组,另一个分配给两个(具有CLOWN和ACROBAT角色的联合)。
如果我们更改权限,我们会在群组级别进行更改。例如,如果我们向ACROBAT组添加swing_on_trapeze权限,则所有杂技演员都会自动继承它。
在Grails术语中,控制器上的权限仍然是角色级别。因此,使用@Secured(['toot_horn'])的操作将允许CLOWN组中的用户,但不允许ACROBAT组中的用户。 @Secured(['receive_applause'])将允许CLOWNS和ACROBATS。
鉴于模型的两层特性(用户,角色),我如何在Spring Security中执行此操作?我是否需要实现自己的自定义身份验证才能通过组收集角色?
谢谢!
答案 0 :(得分:7)
您应该使用新的Spring Security Core plugin,因为Acegi插件尚未开发且基本上已被弃用。
但不管怎样,两个插件都只是期望你的用户类中有一个类似getAuthorities()
方法的东西,它返回角色实例。在这样的场景中,用户有很多组,只需收集所有组的角色:
class User {
...
def getAllRoles() {
Set allRoles = []
groups.each { allRoles.addAll it.roles }
allRoles
}
}
这假设您在用户和组之间有多对多:
static hasMany = [groups: Group]
和Group有多对多角色:
static hasMany = [roles: Role]
要使用此功能,请在SecurityConfig.groovy中将'relationalAuthorities'属性设置为'allRoles',以便它使用它而不是用户和角色之间的多对多:
relationalAuthorities='allRoles'
Spring Security核心插件不需要配置,因为它已经依赖于应用程序定义的getAuthorities方法,所以只需在User类中使用类似的东西:
Set<Role> getAuthorities() {
Set allRoles = []
groups.each { allRoles.addAll it.roles }
allRoles
}