【问题标题】:Handle timeout with SpringSecurity使用 SpringSecurity 处理超时
【发布时间】:2016-09-08 23:53:38
【问题描述】:

我们正在使用 Spring Security 来保护 Web 应用程序,并且我们希望记录登录/注销/超时事件。

请让我解释一下目前的实现:

  1. 处理注销:

我们使用 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);
    }
}

到目前为止,登录和注销都很好,当我们单击注销链接时,我们能够拦截事件并打印用户名。让我们看看超时配置...

  1. 处理超时

为了实现会话超时超时,我们在附加到 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 无关。

说到这里,我有一些问题:

  1. 有没有更好的方法来使用 Spring 处理会话(例如会话超时),这样我们就不必在 ServletContext 中创建侦听器了?
  2. 我们如何才能拦截超时并能够打印类似于“Authentication.getName()”的用户详细信息?

欢迎任何建议或推荐的讲座!

谢谢,祝你有美好的一天!

【问题讨论】:

  • 注册HttpSessionEventPublisher,它会在会话创建和销毁时触发春季事件。没有必要自己搞砸。您可以使用它们来标记会话的开始和结束。当您收到HttpSessionDestroyedEvent 时,您可以计算是超时还是常规注销。

标签: spring session spring-security timeout logout


【解决方案1】:

这里有一些替代方法:

1) 使用 jquery timeout,您可以找到更多免费插件用于您的网络。 (例如:jquery idle timeout

2)曾经,我也为这个问题而苦苦挣扎,我一直在做的解决方法之一是使用沙盒 iframe。在页面和页面末尾显示所有详细信息,放置具有链接的 iframe 以注销用户。

这是一些建议。

【讨论】:

    【解决方案2】:

    这是我在超时时获取用户名的方法:

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSession httpSession = event.getSession();
        long lastAccessedTime = httpSession.getLastAccessedTime();
        int maxInactiveTime = httpSession.getMaxInactiveInterval() * 1000; //millis
        long currentTime = System.currentTimeMillis();
            if ((currentTime - lastAccessedTime) >= maxInactiveTime ){
            //if is a timeout
                SessionInformation i = sessionRegistry().getSessionInformation(event.getSession().getId());
                String username = ((User) i.getPrincipal()).getUsername();
            }
        }
    

    在我的同一个文件中

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-06
      • 1970-01-01
      • 2021-07-02
      • 2013-11-26
      • 2013-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多