2010-07-06 4 views
5

Wir entwickeln eine App (mit Grails Spring Security (ehemals Acegi)), in der wir Tausende von Benutzern haben werden, die 10-15 diskrete Benutzertypen umfassen. Im aktuellen System entspricht jeder Benutzertyp einer "Gruppe", und die spezifischen Rollen und Berechtigungen sind an die Gruppe gebunden. Der Benutzer erhält alle seine "Rollen" aus der Gruppe.Spring Security (Acegi) und Benutzergruppen (vs. Rollen)

Zum Beispiel könnten wir zwei Benutzergruppen haben:

CLOWN: Rollen = ride_clown_car, toot_horn, receive_applause ACROBAT: Rollen = do_flip, walk_tightrope, receive_applause

Wir haben drei Benutzer, eine an die zugewiesene CLOWN-Gruppe, eine der ACROBAT-Gruppe zugewiesene Gruppe und eine, die beiden zugewiesen ist (hat eine Union von CLOWN- und ACROBAT-Rollen).

Wenn wir Berechtigungen ändern, tun wir dies auf Gruppenebene. Wenn wir beispielsweise der ACROBAT-Gruppe eine swing_on_trapeze-Berechtigung hinzufügen, übernehmen alle Akrobaten diese automatisch.

In Grails Begriffe, die Berechtigungen auf den Controllern würden immer noch auf der Rollenebene sein. Eine Aktion mit @Secured (['toot_horn']) würde also Benutzern in der CLOWN-Gruppe, aber nicht in der ACROBAT-Gruppe erlauben. @Secured (['receive_applause']) würde sowohl CLOWNS als auch ACROBATS zulassen.

Wie würde ich dies in Spring Security angesichts der zweistufigen Art des Modells (Benutzer, Rolle) tun? Muss ich meine eigene benutzerdefinierte Authentifizierung implementieren, um rollenbasierte Gruppen zu sammeln?

Danke!

+0

ich etwas bin die Umsetzung sehr ähnlich zu dir. Wie stellst du "grails.plugin.springsecurity.userLookup.authorityJoinClassName" in deinem Fall ein? In einem zweistufigen System könnte dies nur auf die erste Ebene (Benutzergruppe) zeigen, die die tatsächlichen Rollen/Berechtigungen nicht definiert. – sola

Antwort

7

Sie sollten das neue Spring Security Core plugin verwenden, da das Acegi-Plugin nicht entwickelt wird und grundsätzlich veraltet ist.

Wie auch immer, beide Plugins erwarten nur, dass es in Ihrer Benutzerklasse so etwas wie eine getAuthorities()-Methode gibt, die Rolleninstanzen zurückgibt. In einem Szenario wie diesem, wo der Benutzer viele Gruppen hat, sammeln nur alle Rollen Gruppen:

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

Dies setzt voraus, dass Sie eine many-to-many zwischen Benutzern und Gruppen haben:

static hasMany = [groups: Group] 

und Gruppe verfügt über eine many-to-many mit Rolle:

static hasMany = [roles: Role] 

diese die Eigenschaft 'relationalAuthorities' gesetzt verwenden, um 'allRoles' in SecurityConfig.groovy so verwendet, dass anstelle der many-to-many zwischen Benutzer und Rolle:

relationalAuthorities='allRoles' 

Es gibt keine Konfiguration für die Kern-Plugin Spring Security erforderlich, da es bereits getAuthorities auf einer anwendungsdefinierte Methode hängt, also nur so etwas wie dies in Ihrer User-Klasse verwenden:

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

Ah- es war mir nicht in den Sinn gekommen, dass Spring Security nicht direkt auf Rollen zugreift - nur über die Aggregator-Methode auf User. Danke, dass Sie diese einfache, elegante Lösung so schnell veröffentlicht haben! Bin dankbar. Und danke für all deine Arbeit am Plugin selbst! – ecodan

+0

@Burt: Ich implementiere etwas, das dem von ecodan sehr ähnlich ist. Wie ändere ich in diesem Fall "grails.plugin.springsecurity.userLookup.authorityJoinClassName"? – sola

Verwandte Themen