Timeout sessione / sessione in corso con la sicurezza di spring

Sto usando spring / spring-security 3.1 e voglio prendere qualche azione ogni volta che l’utente si disconnette (o se la sessione è scaduta). Sono riuscito a fare l’azione per il logout ma per il timeout della sessione, non riesco a farlo funzionare.

In web.xml ho specificato solo ContextLoaderListener (può essere questo il problema?) E ovviamente DelegatingFilterProxy.

Io uso la configurazione automatica come questa.

          

Il gestore di logout viene chiamato quando l’utente fa clic su Esci, che effettuerà alcune chiamate a un database.

Ma come gestisco il timeout della sessione ???

Un modo per gestirlo sarebbe iniettare il nome utente nella sessione quando l’utente si collega e quindi utilizzare un normale httpsessionlistener e fare la stessa cosa durante il timeout della sessione.

C’è un modo simile con la sicurezza di spring, in modo che quando la spring scopre che la sessione è in timeout, posso collegarmi lì, accedere all’autenticazione e ottenere gli UserDetails da lì e fare la pulizia.

Ho una soluzione più semplice. Funziona sia per il logout che per il timeout della sessione.

 @Component public class LogoutListener implements ApplicationListener { @Override public void onApplicationEvent(SessionDestroyedEvent event) { List lstSecurityContext = event.getSecurityContexts(); UserDetails ud; for (SecurityContext securityContext : lstSecurityContext) { ud = (UserDetails) securityContext.getAuthentication().getPrincipal(); // ... } } } 

web.xml:

  org.springframework.security.web.session.HttpSessionEventPublisher  

Ok, ho trovato una soluzione funzionante, non è buona come vorrei, ma sono io a ottenere il risultato.

Creo un bean da cui posso ottenere una sospensione di ApplicationContext.

 public class AppCtxProvider implements ApplicationContextAware { private static WeakReference APP_CTX; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { APP_CTX = new WeakReference(applicationContext); } public static ApplicationContext getAppCtx() { return APP_CTX.get(); } } 

Implemento HttpSessionEventPublisher e su destroy, ottengo gli UserDetails tramite sessionRegistry.getSessionInfo (sessionId)

Ora ho i fagioli spring che ho bisogno di fare la pulizia della sessione e l’utente per il quale è scaduta la sessione.

 public class SessionTimeoutHandler extends HttpSessionEventPublisher { @Override public void sessionCreated(HttpSessionEvent event) { super.sessionCreated(event); } @Override public void sessionDestroyed(HttpSessionEvent event) { SessionRegistry sessionRegistry = getSessionRegistry(); SessionInformation sessionInfo = (sessionRegistry != null ? sessionRegistry .getSessionInformation(event.getSession().getId()) : null); UserDetails ud = null; if (sessionInfo != null) { ud = (UserDetails) sessionInfo.getPrincipal(); } if (ud != null) { // Do my stuff } super.sessionDestroyed(event); } private SessionRegistry getSessionRegistry() { ApplicationContext appCtx = AppCtxProvider.getAppCtx(); return appCtx.getBean("sessionRegistry", SessionRegistry.class); } 

È ansible utilizzare SimpleRedirectInvalidSessionStrategy per redirect a un URL quando viene rilevata una sessione richiesta non valida da SessionManagementFilter.

Esempio di applicazioneContext sarebbe così:

             

Se si utilizza JSF, fare riferimento anche a JSF 2, Spring Security 3.xe Richfaces 4 reindirizzamento alla pagina di accesso in timeout di sessione per le richieste ajax su come gestire anche le richieste Ajax.

AGGIORNAMENTO : in tal caso, puoi estendere HttpSessionEventPublisher e ascoltare eventi sessionDestroyed come questo:

 package com.examples; import javax.servlet.http.HttpSessionEvent; import org.springframework.security.web.session.HttpSessionEventPublisher; public class MyHttpSessionEventPublisher extends HttpSessionEventPublisher { @Override public void sessionCreated(HttpSessionEvent event) { super.sessionCreated(event); } @Override public void sessionDestroyed(HttpSessionEvent event) { //do something super.sessionDestroyed(event); } } 

e quindi registra questo listener nel tuo web.xml in questo modo:

  com.examples.MyHttpSessionEventPublisher