2012-03-28 6 views
22

Sto facendo un'applicazione con l'autenticazione di OpenID utilizzando Spring Security. Quando l'utente è loggato, alcune autorità vengono caricate nella sua sessione.Come ricaricare le autorizzazioni per l'aggiornamento degli utenti con Spring Security

Possiedo un utente con diritto completo che può modificare le autorizzazioni (revocare, aggiungere ruoli) di altri utenti. La mia domanda è, come cambiare dinamicamente le autorizzazioni della sessione utente? (impossibile usare SecurityContextHolder perché voglio cambiare un'altra sessione Utente).

Modo semplice: invalidare la sessione utente, ma come? Modo migliore: aggiornare la sessione utente con nuove autorità, ma come?

risposta

6

Il punto chiave: si dovrebbe essere in grado di accedere agli utenti SecurityContext s.

Se ci si trova in ambiente servlet e si utilizza come HttpSessionsecurityContextRepository nella vostra securityContextPersistenceFilter, allora si può fare con la molla di SessionRegistry. Per forzare l'utente a re-auth (dovrebbe essere migliore della revoca delle autorizzazioni silenziose) invalidare il suo HttpSession. Non dimenticate di aggiungere HttpSessionEventPublisher a web.xml

<listener> 
    <listener-class> 
     org.springframework.security.web.session.HttpSessionEventPublisher 
    </listener-class> 
</listener> 

Se si utilizza thread-local securityContextRepository, allora si dovrebbe aggiungere filtro personalizzato per springSecurityFilterChain per gestire SecurityContext s Registro di sistema. Per fare ciò devi usare la configurazione di plain-bean springSecurityFilterChain (senza le scorciatoie dello spazio dei nomi security). Con la configurazione in chiaro con filtri personalizzati avrai pieno controllo su autenticazione e autorizzazione.

Alcuni link, non risolvono il problema esattamente (senza OpenID), ma possono essere utili:

7

Grazie, aiutami molto! Con SessionRegistry, posso utilizzare getAllPrincipals() per confrontare l'utente da modificare con gli utenti attivi correnti nelle sessioni. Se esiste una sessione, posso invalidare la sua sessione usando: expireNow() (da SessionInformation) per forzare la ri-autenticazione.

Ma non capisco l'utilità di securityContextPersistenceFilter?

EDIT:

// user object = User currently updated 
// invalidate user session 
List<Object> loggedUsers = sessionRegistry.getAllPrincipals(); 
for (Object principal : loggedUsers) { 
    if(principal instanceof User) { 
     final User loggedUser = (User) principal; 
     if(user.getUsername().equals(loggedUser.getUsername())) { 
      List<SessionInformation> sessionsInfo = sessionRegistry.getAllSessions(principal, false); 
      if(null != sessionsInfo && sessionsInfo.size() > 0) { 
       for (SessionInformation sessionInformation : sessionsInfo) { 
        LOGGER.info("Exprire now :" + sessionInformation.getSessionId()); 
        sessionInformation.expireNow(); 
        sessionRegistry.removeSessionInformation(sessionInformation.getSessionId()); 
        // User is not forced to re-logging 
       } 
      } 
     } 
    } 
} 
+0

'securityContextPersistenceFilter' di default metterà' 'SecurityContext' in HttpSession' in ambiente servlet. Dato che hai già pronto SessionRegistry 'primavera non hai bisogno di personalizzare questo filtro. – alexkasko

+0

Sono nell'ambiente servlet, qual è l'utilità di personalizzare securityContextPersistenceFilter? – Aure77

+0

diversi casi possibili, ad es. 'HttpSession's sono disabilitati e non si desidera l'archiviazione locale dei thread. Quindi puoi usare la tua implementazione di 'securityContextRepository'. Se lo storage 'HttpSession' soddisfa le tue esigenze, allora non c'è utilità. – alexkasko

22

Se è necessario aggiornare dinamicamente un loggato autorità dell'utente (quando queste sono cambiate, per qualsiasi motivo), senza la necessità di effettuare il logout e il login, naturalmente, non vi resta che reimpostare l'oggetto Authentication (token di sicurezza) nella primavera SecurityContextHolder.

Esempio:

Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 

List<GrantedAuthority> updatedAuthorities = new ArrayList<>(auth.getAuthorities()); 
updatedAuthorities.add(...); //add your role here [e.g., new SimpleGrantedAuthority("ROLE_NEW_ROLE")] 

Authentication newAuth = new UsernamePasswordAuthenticationToken(auth.getPrincipal(), auth.getCredentials(), updatedAuthorities); 

SecurityContextHolder.getContext().setAuthentication(newAuth); 
+5

Beh, ha quasi funzionato per me. Questa variabile "auth" riguarda l'utente che ha effettuato l'accesso (ovvero, io). Se sono loggato come "x" e vorrei revocare le autorizzazioni "y", come ottengo l'oggetto di autenticazione da quello specifico utente? – Paulo

Problemi correlati