2015-12-09 3 views
8

Ho configurato la mia sicurezza di primavera per lavorare con i gruppi.grani ruolo di sicurezza primavera e gruppo

Ho usato questo scipt per creare le classi di dominio:

grails s2-quickstart com.yourapp User Role --groupClassName=RoleGroup 

ho pensato che un utente può avere molti gruppi in cui un gruppo può avere molti ruoli

Questo è ciò che un metodo generato assomiglia a la classe User:

Set<RoleGroup> getAuthorities() { 
    UserRoleGroup.findAllByUser(this).collect { it.roleGroup } 
} 

Ma ora ho visto che lo script ha anche creato una classe chiamata UserRole, che è l'associazione tra l'utente e ruolo. Quindi un utente può avere anche molti ruoli direttamente?

Ho provato e viene salvato nel database. Ho modificato il metodo come questo:

def getAuthorities() { 
    def authorities = UserRoleGroup.findAllByUser(this).collect { it.roleGroup } 

    authorities.addAll(UserRole.findAllByUser(this).collect { it.role }) 
    return authorities 
} 

Ora, quando creo una voce nel database in uso < -> associazione ruolo. Non riesco ad accedere più. Prendo il messaggio predefinito per la sicurezza di primavera, in pratica dicendo che non sono state trovate credenziali.

Quando cancello la voce manualmente, posso effettuare nuovamente il login. Penso che questo sia dovuto al fatto che il metodo restituisce solo oggetti RoleGroup.

Le mie domande sono: Gruppi

a) posso anche assegnare i ruoli direttamente quando ho configurato

b) se no, perché è lo script creando questa classe

c) Se sì, Come lo faccio?

risposta

2

Non penso che ci si aspetterebbe di assegnare uno Role direttamente a User quando si utilizza Groups.

Assegnare un Group a Utente e Role a Group.

penso che la struttura del codice presentato potrebbe essere utile quando "declassamento" la vostra applicazione

di utilizzare solo User e Roles, senza rompere il vostro attuale insieme di regole.

1

È solo una mia opinione: script creato UserRole perché solo la classe di ottimizzazione, ad esempio se si riceve Ruolo da db e si cerca di trovare qualche utente in ibernazione, dovrebbe essere ricevuto da tutti gli utenti dal proxy. E 'solo la classe di ottimizzazione. Se si desidera un ruolo per utente, è possibile impostarlo in UserRole.create() Aggiungi restrizione e dovrebbe funzionare. Spero che mi capirai e ti ho capito bene. Buona giornata

0

un po 'vecchio, ma potrebbe venire in mano per chiunque altro cercando gruppi:

Nella classe User:

Set<RoleGroup> getAuthorities() { 
    (UserRoleGroup.findAllByUser(this) as List<UserRoleGroup>)*.roleGroup as Set<RoleGroup> 
} 



Set<Role> getRoles() { 
    (UserRoleGroup?.findAllByUser(this)?.roleGroup?.authorities.collect{it}?.flatten() ?: oldRoles) as Set<Role> 
} 

List<String> getRoleNames() { 
     (UserRoleGroup?.findAllByUser(this)?.roleGroup?.collect{it.authorities.authority}?.flatten()?: oldRoles.authority) as List<String> 
} 

//Above will look up from userRoleGroup roleGroup.authorities = UserRole below 
Set<Role> getOldRoles() { 
    (UserRole.findAllByUser(this) as List<Role>)*.role as Set<Role> 
} 

ero stato utilizzando i ruoli, anche se i gruppi sono stati abilitati ed autenticazione contro i vecchi oldRoles metodo:

import grails.plugin.springsecurity.userdetails.GormUserDetailsService 
import grails.transaction.Transactional 
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken 
import org.springframework.security.core.Authentication 
import org.springframework.security.core.GrantedAuthority 
import org.springframework.security.core.authority.SimpleGrantedAuthority 
import org.springframework.security.core.context.SecurityContextHolder 
import org.springframework.security.core.userdetails.UserDetails 
import org.springframework.security.core.userdetails.UsernameNotFoundException 

class MySpringSecurityAuthenticator extends GormUserDetailsService{ 

    UserDetails loadUserByUsername(String username, boolean loadRoles) 
      throws UsernameNotFoundException { 
     return loadUserByUsername(username) 
    } 

    @Transactional 
    UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { 
     //enable login with either username or password 
     User user = User.find { 
      username == username || attributes.emailAddress == username || userCode == username 
     } 
     //if (!user) throw new UsernameNotFoundException('User not found', username) 
     if (!user) throw new UsernameNotFoundException('User not found') 
     return loadUserByUsername(user) 
    } 
    @Transactional 
    UserDetails loadUserByUsername(User user) throws UsernameNotFoundException { 
     if (!user) throw new UsernameNotFoundException('User not found') 
     //UserDetails.withNewSession { 
//getAuthorities(user.oldRoles) 
      UserDetails userDetails = new org.springframework.security.core.userdetails.User(user.username, user.password, 
        user.enabled, !user.accountExpired, !user.passwordExpired, !user.accountLocked,getAuthoritiesFromGroup(user.authorities)) 
      Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()) 
      SecurityContextHolder.getContext().setAuthentication(authentication) 
      return userDetails 
     //} 
    } 

    public static List<GrantedAuthority> getAuthoritiesFromGroup(Set<RoleGroup> roles) { 
     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>() 
     roles?.each { role -> 
      println "-- role = ${role} vs ${role.getClass()}" 
      authorities.add(new SimpleGrantedAuthority(role.name)) 
     } 
     return authorities 
    } 
    public static List<GrantedAuthority> getAuthorities(Set<Role> roles) { 
     List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>() 
     roles?.each { role -> 
      println "-- role = ${role} vs ${role.getClass()}" 
      authorities.add(new SimpleGrantedAuthority(role.authority)) 
     } 
     return authorities 
    } 
} 

e nella mia primavera/resources.groovy:

userDetailsService(MySpringSecurityAuthenticator){ 
    grailsApplication = ref('grailsApplication') 
} 

Quanto sopra aveva fatto finora è stato tornare a ruoli utente e l'aggiunta di loro per l'autenticazione tramite gestore .. getAuthorities (user.oldRoles)

ora ho cambiato il metodo di cui sopra per leggere i nomi dei gruppi tramite getAuthoritiesFromGroup (user.authorities)

Questo analizza semplicemente i nomi dei gruppi, che come un lato (effetto) di versione che sto usando devono includere anche la parola ROLE_GROUPNAME

Così ora se creare

@Transactional 
def grantPermission(User user, String role='ROLE_ADMIN', String group='ROLE_SUPERGROUP') { 
    def adminRole = Role.findByAuthority(role) 
    if (!adminRole) { 
     adminRole = new Role(authority: role).save(flush: true) 

    } 
    UserRole.create user, adminRole, true 

    def adminRoleGroup = RoleGroup.findByName(group) 
    if (!adminRoleGroup) { 
     adminRoleGroup = new RoleGroup(name: group).save(flush: true) 
    } 
    def adminRoleGroupRole = RoleGroupRole.findByRole(adminRole) 
    if (!adminRoleGroupRole) { 
     adminRoleGroupRole = new RoleGroupRole(role: adminRole, roleGroup: adminRoleGroup).save(flush: true) 
    } 
    def alreadyDone = UserRoleGroup.findByUserAndRoleGroup(user,adminRoleGroup) 
    if (!alreadyDone) { 
     new UserRoleGroup(user: user, roleGroup: adminRoleGroup).save(flush: true) 
    } 
} 

mi aspetto di autenticazione con i nomi dei gruppi e non i ruoli utente in modo insomma ho dovuto cambiare il mio controller per

@Secured("hasAnyRole('ROLE_SUPERGROUP')") 

speranza ha senso dovrebbe essere semplice da seguire vuole solo tempo per ottenere la tua testa intorno a tutto ..

A questo punto sto ancora giocando e non vorrei usare come risposta concreta dato che sono un po 'come hackerarlo per aggiungere i miei gruppi come le mie autorità e se volessi potrebbe aggiungere un altro gancio per andare oltre attraverso ciascuno di quei gruppi e ciascuno dei ruoli effettivi in ​​esso pure - non so cosa produrrà - al momento

Voglio cambiarlo in requestMaps e spostarlo in db quindi molto da cambiare e deciderò se dovrei tornare indietro o usare i gruppi so che in questo modo posso configurare meno nomi sui controller e fare affidamento sui nomi dei gruppi ..

in entrambi i casi la sua sotto il cofano di tutto e ti dà una chiara idea di qualche anno su, ma può tornare utile per gli altri

aggiornamento così ho deciso di andare con: ,getAuthorities(user.roles)

Dove Set<Role> getRoles() { metodo all'interno del po 'sopra di codice

La ragione è abbastanza semplice:

results?.each { 
      it.user=User.get(it.id) 
      println "-- \n${it.id}:${it.user.roles} \n${it.id}:${it.user.oldRoles}" 


7:[Role(authority:ROLE_ADMIN), Role(authority:ROLE_ADMINAHHA)] 
7:[Role(authority:ROLE_ADMIN)] 

Come potete vedere ho aggiunto un nuovo utente utilizzando i getOldRoles vedo solo 1 ruolo sulle getRoles ottengo 2 ruoli .. Ho aggiunto utente con 2 ruoli ..

Quindi questo ora analizzerà tutti i ruoli utente e li aggiungerà a List<GrantedAuthority> l'autenticazione sarà ancora tramite i nomi RUOLO effettivi generati come in precedenza.

Significa solo quando ho disattivare un gruppo da parte dell'utente dovrebbe interrompere il caricamento che il permesso per l'utente ..

questo è ciò che il modello dovrebbe fare