Logout/Session超时捕获spring security

Per*_*rre 32 java spring-security session-timeout

我正在使用spring/spring-security 3.1并希望在用户注销时(或者如果会话超时)采取某些操作.我设法为注销完成了操作,但是对于会话超时,我无法使其正常工作.

在web.xml中我只指定了ContextLoaderListener(这可能是问题吗?),当然还有DelegatingFilterProxy.

我像这样使用自动配置.

    <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>
Run Code Online (Sandbox Code Playgroud)

当用户单击注销时,将调用注销处理程序,这将调用数据库.

但是如何处理会话超时???

处理它的一种方法是在用户登录时将用户名注入会话,然后使用普通的httpsessionlistener并在会话超时时执行相同的操作.

弹簧安全性是否有类似的方式,因此当spring发现会话超时时,我可以在那里挂钩,访问Authentication并从那里获取UserDetails并进行清理.

Joh*_*n29 57

我有一个更简单的解决方案.这适用于注销和会话超时.

@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();
            // ...
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

web.xml中:

<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)

  • @yathirigan不确定你对"Spring Security会话"的意思.Spring Security使用HTTP会话,所以基本上它是一样的. (5认同)
  • > Spring Security使用HTTPSession <哦确定..感谢您的澄清.我读过的几篇文章(作为春季会议的初学者)似乎表明Spring Security中讨论的会话与HTTPSession不同.这就是我有这种困惑的原因. (2认同)

Per*_*rre 7

好吧,我有一个解决方案正在运行,它不如我想的那么好,但它让我得到了结果.

我创建了一个bean,我可以从中获取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();
}
}
Run Code Online (Sandbox Code Playgroud)

我实现HttpSessionEventPublisher并在销毁时,我通过sessionRegistry.getSessionInfo(sessionId)获取UserDetails

现在我有了一个spring bean,我需要对会话进行清理以及会话超时的用户.

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);
}
Run Code Online (Sandbox Code Playgroud)