2010-07-06 22 views
5

Estamos desarrollando una aplicación (utilizando Grails Spring Security (anteriormente Acegi)) en la que tendremos miles de usuarios que abarcan de 10 a 15 tipos de usuarios discretos. En el sistema actual, cada tipo de usuario equivale a un "grupo", y los roles y permisos específicos están vinculados al grupo. El usuario obtiene todos sus "roles" del grupo.Spring Security (Acegi) y grupos de usuarios (frente a Roles)

Por ejemplo, podríamos tener dos grupos de usuarios:

PAYASO: papeles = ride_clown_car, toot_horn, receive_applause ACRÓBATA: papeles = do_flip, walk_tightrope, receive_applause

Tenemos tres usuarios, asignado a la Grupo CLOWN, uno asignado al grupo ACROBAT y otro asignado a ambos (tiene una unión de roles CLOWN y ACROBAT).

Si cambiamos los permisos, lo hacemos a nivel de grupo. Por ejemplo, si agregamos un permiso swing_on_trapeze al grupo ACROBAT, todos los acróbatas lo heredarán automáticamente.

En términos de Grails, los permisos en los controladores seguirían estando en el nivel de rol. Entonces, una acción con @Secured (['toot_horn']) permitiría a los usuarios del grupo CLOWN pero no del grupo ACROBAT. @Secured (['receive_applause']) permitiría tanto CLOWNS como ACROBATS.

¿Cómo haré esto en Spring Security dada la naturaleza de dos niveles del modelo (usuario, rol)? ¿Debo implementar mi propia autenticación personalizada para recopilar roles basados ​​en grupos?

Gracias!

+0

Me estoy poniendo en práctica algo muy similar al tuyo ¿Cómo configura "grails.plugin.springsecurity.userLookup.authorityJoinClassName" en su caso? En un sistema de dos niveles, esto solo podría apuntar al primer nivel (grupo de usuarios) que no define los roles/autoridades reales. – sola

Respuesta

7

Debe utilizar el nuevo Spring Security Core plugin ya que el complemento Acegi no se está desarrollando y está básicamente obsoleto.

Pero de cualquier forma, ambos plugins solo esperan que haya algo así como un método getAuthorities() en su clase de usuario que devuelva instancias de roles. En un escenario como éste, donde el usuario tiene muchos grupos, simplemente recoger todos los papeles de los grupos:

class User { 
    ... 
    def getAllRoles() { 
     Set allRoles = [] 
     groups.each { allRoles.addAll it.roles } 
     allRoles 
    } 
} 

Esto supone que tiene una relación muchos-a-muchos entre el Usuario y Grupo:

static hasMany = [groups: Group] 

y el Grupo tiene una relación muchos-a-muchos con Papel:

static hasMany = [roles: Role] 

para utilizar este conjunto propiedad de los 'relationalAuthorities' a '' allRoles en SecurityConfig.groovy por lo que utiliza que en lugar de los muchos-a-muchos entre usuario y rol:

relationalAuthorities='allRoles' 

No hay necesidad de configuración para el complemento del núcleo de Seguridad primavera ya que depende de un método getAuthorities definido por la aplicación ya, por lo que sólo tiene que utilizar algo como esto en su clase de usuario:

Set<Role> getAuthorities() { 
    Set allRoles = [] 
    groups.each { allRoles.addAll it.roles } 
    allRoles 
} 
+0

Ah, no se me había ocurrido que Spring Security no acceda directamente a Roles, solo a través del método agregador en Usuario. ¡Gracias por publicar esta solución simple y elegante tan rápido! Lo aprecio. ¡Y gracias por todo tu trabajo en el plugin en sí! – ecodan

+0

@Burt: Estoy implementando algo muy similar a Ecodan. ¿Cómo cambio "grails.plugin.springsecurity.userLookup.authorityJoinClassName" en este caso? – sola

Cuestiones relacionadas