2012-03-28 9 views
22

Estoy haciendo una aplicación con autenticación de OpenID con Spring Security. Cuando el usuario inicia sesión, algunas autoridades se cargan en su sesión.Cómo recargar las autoridades de la actualización del usuario con Spring Security

Tengo un usuario con pleno derecho que puede modificar las autoridades (revocar, agregar roles) de otros usuarios. Mi pregunta es, ¿cómo cambiar las autorizaciones de la sesión de usuario dinámicamente? (no se puede usar SecurityContextHolder porque quiero cambiar otra sesión de usuario).

Manera simple: invalidar la sesión del usuario, pero ¿cómo? Mejor manera: actualizar la sesión del usuario con nuevas autoridades, pero ¿cómo?

Respuesta

6

El punto clave: usted debe poder acceder a los usuarios SecurityContext s.

Si se encuentra en el medio ambiente y el servlet está utilizando HttpSession como securityContextRepository en su securityContextPersistenceFilter, a continuación, se puede hacer con el resorte de SessionRegistry. Para forzar al usuario a volver a autenticar (debe ser mejor que la revocación de permisos silenciosos), invalide su HttpSession. No se olvide de añadir HttpSessionEventPublisher a web.xml

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

Si está utilizando local de subprocesos securityContextRepository, a continuación, se debe añadir filtro personalizado para springSecurityFilterChain para gestionar SecurityContext s Registro. Para hacerlo, debe utilizar la configuración springSecurityFilterChain de liso simple (sin security accesos directos del espacio de nombres). Con la configuración de grano simple con filtros personalizados, tendrá control total sobre la autenticación y la autorización.

Algunos enlaces, no resuelven su problema exactamente (sin OpenID), pero pueden ser útiles:

7

Gracias, ayúdame mucho! Con SessionRegistry, puedo usar getAllPrincipals() para comparar el usuario a modificar con los usuarios activos actuales en las sesiones. Si existe una sesión, puedo invalidar su sesión usando: expireNow() (desde SessionInformation) para forzar la reautenticación.

Pero no entiendo la utilidad de 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' por defecto pondrá' SecurityContext' en 'HttpSession' en el entorno de servlet. Como ya tiene Spring Session 'SessionRegistry', no necesita personalizar este filtro. – alexkasko

+0

Estoy en el entorno de servlet, ¿cuál es la utilidad de personalizar securityContextPersistenceFilter? – Aure77

+0

diferentes casos posibles, p. 'HttpSession's está deshabilitado y no desea el almacenamiento local de subprocesos. Entonces puede usar su propia implementación de 'securityContextRepository'. Si el almacenamiento 'HttpSession' satisface sus necesidades, entonces no hay utilidad. – alexkasko

22

Si es necesario actualizar dinámicamente un registran en las autoridades del usuario (cuando éstos han cambiado, por cualquier razón), sin tener que salir y entrar en el supuesto, sólo tiene que reinicie el objeto Authentication (token de seguridad) en el resorte SecurityContextHolder.

Ejemplo:

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

Bueno, casi funcionó para mí. Esta variable "auth" se refiere al usuario que ha iniciado sesión (es decir, a mí). Si estoy conectado como "x" y me gustaría revocar a las autoridades "y", ¿cómo obtengo el objeto de Autenticación de ese usuario específico? – Paulo

Cuestiones relacionadas