Spring Security(Acegi)和用户组(vs.角色)

eco*_*dan 5 grails spring-security

我们正在开发一个应用程序(使用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中执行此操作?我是否需要实现自己的自定义身份验证才能通过组收集角色?

谢谢!

Bur*_*ith 7

您应该使用新的Spring Security Core插件,因为Acegi插件尚未开发且基本上已被弃用.

但无论哪种方式,两个插件都只是期望getAuthorities()在您的用户类中返回角色实例的方法.在这样的场景中,用户有很多组,只需收集所有组的角色:

class User {
   ...
   def getAllRoles() {
      Set allRoles = []
      groups.each { allRoles.addAll it.roles }
      allRoles
   }
}
Run Code Online (Sandbox Code Playgroud)

这假设您在用户和组之间有多对多:

static hasMany = [groups: Group]
Run Code Online (Sandbox Code Playgroud)

和Group有多对多的角色:

static hasMany = [roles: Role]
Run Code Online (Sandbox Code Playgroud)

要使用此功能,请在SecurityConfig.groovy中将'relationalAuthorities'属性设置为'allRoles',以便它使用它而不是用户和角色之间的多对多:

relationalAuthorities='allRoles'
Run Code Online (Sandbox Code Playgroud)

Spring Security核心插件不需要配置,因为它已经依赖于应用程序定义的getAuthorities方法,所以只需在User类中使用类似的东西:

Set<Role> getAuthorities() {
   Set allRoles = []
   groups.each { allRoles.addAll it.roles }
   allRoles
}
Run Code Online (Sandbox Code Playgroud)