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

时间:2010-07-06 20:01:58

标签: 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中执行此操作?我是否需要实现自己的自定义身份验证才能通过组收集角色?

谢谢!

1 个答案:

答案 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
}