java - 为什么 SessionDestroyedEvent 会触发两次?

标签 java spring spring-security logout

我有以下 session 销毁监听器:

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>

P.P.S

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

最佳答案

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

在首次登录期间,Spring 安全性会销毁此默认 session ,并创建它自己的 session 实例,与特定用户关联。

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

这就是该事件触发两次的原因。当您第一次登录时,Spring 会销毁默认容器的 session 。当您第二次登录时,您的 session 策略类会破坏用户之前的 session 。

关于java - 为什么 SessionDestroyedEvent 会触发两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35523394/

相关文章:

java - 如何用java画框图?

java - 无法加载 JDBC 驱动程序。为什么? ( Spring , hibernate )

java - 通过检查字典进行 Spring 验证

java - 在 Spring Security 中手动过期(失效)后 session 不会被销毁

java - eclipse 要求我在 finally block 中用 try/catch 包围 - 可以禁用它吗?

java - 如何通过 listView 中按下的按钮访问主 Activity 中的数据?

相当于 Ada Select 语句的 Java

spring - Gradle Spring Boot 依赖项未找到多模块项目

spring - 使用 Thymeleaf Security 为匿名用户显示特定内容

java - 转发后是否允许重定向请求?