为什么SessionDestroyedEvent会激发两次?

时间:2016-02-20 12:40:41

标签: java spring spring-security logout

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

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。

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

P.S。

spring security configuration:

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

P.P.S

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

1 个答案:

答案 0 :(得分:0)

Spring基于servlet工作的事实。 Servlet容器(例如Tomcat)默认创建会话实例(libjpeg-turbo cross-compile to Android fails)。此会话实例与Spring安全性无关。

首次登录时,Spring安全会破坏此默认会话,并创建自己的会话实例,并与某个用户关联。

但对于ApplicationListener(实际上通知CREATE DOMAIN my_bytea_8 AS bytea CHECK(length(value) <= 8); postgres=# SELECT 'NAZDARBAZAR'::my_bytea_8; ERROR: 23514: value for domain my_bytea_8 violates check constraint "my_bytea_8_check" SCHEMA NAME: public DATATYPE NAME: my_bytea_8 CONSTRAINT NAME: my_bytea_8_check LOCATION: ExecEvalCoerceToDomain, execQual.c:4042 )并不重要,这个会话实例是否与Spring安全相关​​。它只是监听会话中发生的事件,并通知其他人。

这就是为什么这个事件会引发两次。当您第一次登录时,Spring会破坏默认容器的会话。当您第二次登录时,您的会话策略类会破坏用户之前的会话。