Captura de tiempo de espera de sesión / sesión con seguridad de spring

Estoy usando spring / spring-security 3.1 y quiero tomar alguna medida cada vez que el usuario cierre la sesión (o si la sesión se agota). Me las arreglé para hacer la acción para cerrar la sesión, pero para el tiempo de espera de la sesión, no puedo hacer que funcione.

En web.xml, solo tengo el ContextLoaderListener especificado (¿puede ser este el problema?) Y, por supuesto, DelegatingFilterProxy.

Utilizo la configuración automática de esta manera.

          

Se llama al controlador de desconexión cuando el usuario hace clic en cerrar sesión, lo que hará que algunas llamadas a una base de datos.

¿Pero cómo manejo el tiempo de espera de la sesión?

Una forma de manejarlo sería inyectar el nombre de usuario en la sesión cuando el usuario inicie sesión y luego use un httpsessionlistener ordinario y haga lo mismo en el tiempo de espera de la sesión.

¿Hay alguna manera similar con la seguridad de spring, de modo que cuando la spring descubre que la sesión ha expirado, puedo conectarme allí, acceder a la Autenticación y obtener los detalles del usuario desde allí y hacer la limpieza.

Tengo una solución más simple. Esto funciona tanto para el cierre de sesión como para el tiempo de espera de la sesión.

 @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, tengo una solución funcionando, no es tan buena como me gustaría, pero me lleva al resultado.

Creo un bean desde el cual puedo obtener el 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(); } } 

Implemente HttpSessionEventPublisher y en destroy, obtengo los UserDetails a través de sessionRegistry.getSessionInfo (sessionId)

Ahora tengo los beans de spring que necesito para la limpieza de la sesión y el usuario para el que se agotó el tiempo de espera de la sesión.

 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); } 

Puede usar SimpleRedirectInvalidSessionStrategy para redirigir a una URL cuando SessionManagementFilter detecta una sesión solicitada no válida.

La muestra applicationContext sería así:

             

Si está utilizando JSF, consulte también JSF 2, Spring Security 3.x y Richfaces 4 redirigir a la página de inicio de sesión en el tiempo de espera de la sesión para solicitudes ajax sobre cómo manejar las solicitudes Ajax también.

ACTUALIZACIÓN : en tal caso, puede extender HttpSessionEventPublisher y escuchar los eventos de la sesión destruida como este:

 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); } } 

y luego registra este oyente en tu web.xml de la siguiente manera:

  com.examples.MyHttpSessionEventPublisher