java - minutes - spring security session expired time
Captura de tiempo de espera de sesión/sesión con seguridad de primavera (3)
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<ApplicationContext> APP_CTX;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
APP_CTX = new WeakReference<ApplicationContext>(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 primavera 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);
}
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.
<security:http auto-config="false" use-expressions="false">
<security:intercept-url pattern="/dialog/*"
access="ROLE_USERS" />
<security:intercept-url pattern="/boa/*"
access="ROLE-USERS" />
<security:intercept-url pattern="/*.html"
access="ROLE-USERS" />
<security:form-login login-page="/auth/login.html"
default-target-url="/index.html" />
<security:logout logout-url="/logout"
invalidate-session="true"
delete-cookies="JSESSIONID" success-handler-ref="logoutHandler" />
</security:http>
<bean id="logoutHandler" class="com.bla.bla.bla.LogoutHandler">
<property name="logoutUrl" value="/auth/logout.html"/>
</bean>
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 primavera, de modo que cuando la primavera 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<SessionDestroyedEvent> {
@Override
public void onApplicationEvent(SessionDestroyedEvent event)
{
List<SecurityContext> lstSecurityContext = event.getSecurityContexts();
UserDetails ud;
for (SecurityContext securityContext : lstSecurityContext)
{
ud = (UserDetails) securityContext.getAuthentication().getPrincipal();
// ...
}
}
}
web.xml:
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
Puede usar SimpleRedirectInvalidSessionStrategy para redirigir a una URL cuando SessionManagementFilter detecta una sesión solicitada no válida.
La muestra applicationContext sería así:
<http>
<custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
<http>
<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" />
<beans:property name="invalidSessionStrategy" ref="simpleRedirectInvalidSessionStrategy " />
</beans:bean>
<beans:bean id="simpleRedirectInvalidSessionStrategy" class="org.springframework.security.web.session.SimpleRedirectInvalidSessionStrategy">
<beans:constructor-arg name="invalidSessionUrl" value="/general/logins/sessionExpired.jsf" />
<beans:property name="createNewSession" value="false" />
</beans:bean>
<beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
Si está utilizando JSF, consulte también JSF 2, Spring Security 3.xy 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 de 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:
<listener>
<listener-class>com.examples.MyHttpSessionEventPublisher</listener-class>
</listener>