注销时如何使用户会话无效?

Posted

技术标签:

【中文标题】注销时如何使用户会话无效?【英文标题】:How Invalidate users sessions when makes logout? 【发布时间】:2012-01-24 16:24:51 【问题描述】:

我花了很多时间来解决这个问题,但仍然无法解决。

我正在使用 Spring Security。该应用程序将在多个服务器上运行。我在登录时使用“记住我”选项将持久登录信息保存在我的数据库中。

如果用户连接到服务器 1,他在 cookie 浏览器中有一个会话 ID。我打开另一台服务器,此用户进行身份验证,cookie 浏览器具有此会话 ID 和服务器 1 连接的会话 ID。

当该用户在一台服务器或另一台服务器上注销时,他应该被重定向到所有服务器的登录页面。

我试图从浏览器中删除 cookie,但没有成功。我怎样才能使这项工作?有什么帮助吗?

示例场景:在 gmail 中,如果您的帐户中打开了 2 个标签,并且如果您从其中一个中注销,则其他标签也会自动注销。服务器 1 不知道服务器 2 的信息。我想我的问题就在这里,但我不知道如何解决这个问题。

这是我的安全配置:

<http auto-config="false" use-expressions="true" disable-url-rewriting="true">
   <intercept-url pattern="/login.do" access="permitAll" />
   <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
   <remember-me data-source-ref="dataSource" />
   <form-login login-page="/login.do" />
   <custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
   <custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
   <session-management session-authentication-strategy-ref="sas" />
</http>

<!-- <logout logout-url="/j_spring_security_logout" logout-success-url="/" invalidate-session="true" /> -->

<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
   <beans:constructor-arg value="/login.do" />
   <beans:constructor-arg>
      <beans:list>
         <beans:ref bean="rememberMeServices"/>
         <beans:ref bean="logoutHandler"/>
      </beans:list>
   </beans:constructor-arg>
   <!-- <beans:property name="filterProcessesUrl" value="/login.do" /> -->
</beans:bean>

<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />

<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
   <beans:property name="sessionRegistry" ref="sessionRegistry" />
   <beans:property name="expiredUrl" value="/login.do" />
</beans:bean>

<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
   <beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
   <beans:property name="maximumSessions" value="1" />
</beans:bean>

<authentication-manager alias="authenticationManager">
   <authentication-provider user-service-ref="jdbcUserService" />
</authentication-manager>

【问题讨论】:

【参考方案1】:

以下是适用于多服务器方案的 3 个解决方案:

    在负载平衡器上使用粘性会话,以便用户不断返回到同一台服务器。然后,您只需在他们注销时使会话无效。这通常与会话故障转移解决方案 (Tomcat example) 结合使用,因此如果服务器出现故障,用户可以被重定向到接收旧会话的新服务器。

    为会话使用分布式缓存(例如Terracotta Web Sessions)。然后当他们注销时使会话失效,并且它将在任何地方失效。

    另一个解决方案是使用自定义的 Spring Security TokenBasedRememberMeServices 作为您的“登录”cookie。如果用户没有选择记住我,请继续设置 cookie,但将其设置为浏览器会话 cookie 而不是持久性 cookie。所有服务器都将识别用户并为其创建会话。当用户注销时,删除 cookie。您还需要一个自定义的 RememberMeAuthenticationFilter 来查找会话中的身份验证令牌和丢失的 RememberMe cookie,如果是这种情况,则使会话无效并清除安全上下文。

【讨论】:

【参考方案2】:

我建议您查看 SessionRegistry 。您可以查看此 here 。 Is it possible to invalidate a spring security session? 对此进行了讨论。也看看这个

Spring 会话存储为 JsessionID cookie。查看here 了解有关删除 cookie 的讨论。

Invalid a session when user makes logout (Spring) 讨论了相同的查询。

【讨论】:

其实这整个答案都是单服务器的答案。

以上是关于注销时如何使用户会话无效?的主要内容,如果未能解决你的问题,请参考以下文章

如何记录 tomcat 会话失效或用户注销

使Java HTTP会话无效以重定向到其他服务器,而无需将用户注销

用户注销时会话无效(Spring)

当他使用相同的凭据登录两次时如何使用户会话无效

其中 jsonwebtoken 存储在服务器 nodejs 中。用户注销后如何使 JWT 过期

如何在 Spring 中处理不成功的注销?