【问题标题】:Why SessionDestroyedEvent fires twice?为什么 SessionDestroyedEvent 触发两次?
【发布时间】:2016-06-02 02:15:17
【问题描述】:

我有以下会话破坏监听器:

public class SessionStateListener implements ApplicationListener {
    private static final Logger LOGGER = LoggerFactory.getLogger(SessionStateListener.class);

    @Override
    public void onApplicationEvent(ApplicationEvent event) {            
        if (event instanceof SessionDestroyedEvent) {               
            System.out.println("log out");            
        }
    }
}

我已经以 user1 身份登录,然后我再次以 user1 身份打开另一个浏览器。

之后我看到"log out" 输出了两次。
对我来说,预期结果 - 1.

你能解释一下这种行为吗?

附言

spring 安全配置:

<bean id="concurrentSessionControlAuthenticationStrategy" class="com.MyConcurrentSessionControlAuthenticationStrategy">
    <constructor-arg name="sessionRegistry" ref="mySessionRegistry" />
    <property name="maximumSessions" value="1" />
</bean>

附言

即使我是第一个用户第一次登录,此事件也会触发

【问题讨论】:

  • 嗯,你说的另一个浏览器是什么意思?如果它真的是一个不同的浏览器(比如 1 的 firefox 和 2 的 chrome),那么您打开 2 个不同的会话,最后关闭 2 个会话,即使它们涉及同一个用户。
  • 两个独立的浏览器会打开两个独立的会话。因为一个浏览器对已经在另一个浏览器中打开的会话一无所知。
  • @Serge Ballesta 请注意我的 P.S.部分
  • @Ken Bekov 看看我的 P.S.部分。我使用 spring security 禁止它
  • 所以你已经实现了一个自定义的并发会话控制策略。你实施了什么策略?关闭上一个会话?关闭新的?关闭两者?

标签: java spring spring-security logout


【解决方案1】:

Spring 基于 servlet 工作的事实。 Servlet 容器(例如 Tomcat)默认创建会话实例(StandardSession)。此会话实例与 Spring 安全性无关。

在首次登录时,Spring 安全性会破坏这个默认会话,并创建它自己的会话实例,与特定用户相关联。

但是对于HttpSessionEventPublisher(实际上是通知ApplicationListener)来说,这个会话实例是否与Spring 安全相关并不重要。它只是监听会话中发生的事件,并通知其他人。

这就是此事件触发两次的原因。当您第一次登录时,Spring 会破坏默认容器的会话。当您第二次登录时,您的会话策略类会破坏用户的上一个会话。

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 1970-01-01
    • 2017-01-08
    • 1970-01-01
    • 2011-01-27
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 2014-10-05
    相关资源
    最近更新 更多