【发布时间】:2016-09-08 23:53:38
【问题描述】:
我们正在使用 Spring Security 来保护 Web 应用程序,并且我们希望记录登录/注销/超时事件。
请让我解释一下目前的实现:
- 处理注销:
我们使用 java config 并且登录/注销工作正常,我们使用 logoutSuccessHandler() 捕获注销事件和会话详细信息,例如用户名。但是,这仅在单击注销链接时有效,而在发生超时时无效。
在配置类中:
.and().formLogin().loginPage("/login").permitAll()
.and().logout().permitAll().logoutSuccessHandler(customLogoutSuccessHandler);
和处理程序定义:
@Component
public class LogoutSuccessHandler extends SimpleUrlLogoutSuccessHandler {
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException, ServletException {
if (authentication != null) {
System.out.println("This user is closing the session: " + authentication.getName());
}
super.onLogoutSuccess(request, response, authentication);
}
}
到目前为止,登录和注销都很好,当我们单击注销链接时,我们能够拦截事件并打印用户名。让我们看看超时配置...
- 处理超时
为了实现会话超时超时,我们在附加到 ServletContext 的侦听器中配置它:
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session created");
event.getSession().setMaxInactiveInterval(15);
}
@Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session destroyed");
}
}
然后在初始化器中:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new SessionListener());
}
通过上面的代码,我们能够在 sessionDestroyed() 方法中拦截超时,但此时 HttpSessionEvent 与 Spring 会话完全无关(例如,无法访问用户名)。
我确信我们缺少将 HttpSession 与 Spring 联系起来的东西。在我看来,我们的会话过期配置与 Spring 无关。
说到这里,我有一些问题:
- 有没有更好的方法来使用 Spring 处理会话(例如会话超时),这样我们就不必在 ServletContext 中创建侦听器了?
- 我们如何才能拦截超时并能够打印类似于“Authentication.getName()”的用户详细信息?
欢迎任何建议或推荐的讲座!
谢谢,祝你有美好的一天!
【问题讨论】:
-
注册
HttpSessionEventPublisher,它会在会话创建和销毁时触发春季事件。没有必要自己搞砸。您可以使用它们来标记会话的开始和结束。当您收到HttpSessionDestroyedEvent时,您可以计算是超时还是常规注销。
标签: spring session spring-security timeout logout