java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?

标签 java spring spring-mvc spring-security

Spring 的 SecurityContextLogoutHandler 指出 clearAuthentication 标志用于:

removes the Authentication from the SecurityContext to prevent issues with concurrent requests.

SecurityContext 中删除 Authentication 可以避免什么具体问题?为什么仅仅使 session 无效(这是 SecurityContextLogoutHandler 的另一职责)还不够?

不清除 SecurityContext 是否担心 SecurityContextPersistenceFilter 可能会将当前身份验证保留到新的 session ID?仅通过新 session 有效地让用户保持登录状态?

最佳答案

What is SecurityContextLogoutHandler?

SecurityContextLogoutHandler 是实现 LogoutHandler 的处理程序。

What SecurityContextLogoutHandler does?

  1. 它通过修改 SecurityContextHolder 执行注销。
  2. 如果 isInvalidateHttpSession() 也会使 HttpSession 无效 为真且 session 不为空。
  3. 它还将从当前的身份验证中删除身份验证 SecurityContext 如果 clearAuthentication 设置为 true(默认)。

Is SecurityContextHolder thread safe?

是的,默认策略 (MODE_THREADLOCAL) 是线程安全的(只要您不尝试即时更改策略)。但是,如果您希望生成的线程继承父线程的 SecurityContext,则应设置 MODE_INHERITABLETHREADLOCAL。

此外,方面没有任何“线程逻辑”,它们与建议的方法在同一线程中执行。

归功于@ axtavt

What is authentication in Spring Security?

身份验证:该框架尝试使用提供的凭据来识别最终用户。可以针对插入 Spring Security 的第三方系统完成身份验证。

让我们考虑一个大家都熟悉的标准身份验证场景。

  1. 系统会提示用户使用用户名和密码登录。
  2. 系统(成功)验证密码是否正确 用户名。
  3. 获取该用户的上下文信息(他们的列表 角色等等)。

为用户建立安全上下文 用户继续执行某些操作,这些操作可能受到访问控制机制的保护,该机制根据当前安全上下文信息检查操作所需的权限。

前三项构成了身份验证过程,因此我们将了解这些在 Spring Security 中是如何发生的。

  1. 获取用户名和密码并组合成一个实例 UsernamePasswordAuthenticationToken 的一个实例 身份验证接口(interface),我们之前看到过)。
  2. token 被传递给 AuthenticationManager 的实例 验证。
  3. AuthenticationManager 返回一个完全填充的 Authentication 成功验证的实例。
  4. 安全上下文是通过调用建立的 SecurityContextHolder.getContext().setAuthentication(...), 通过 在返回的身份验证对象中。

SecurityContextPersistentFilter

这个名字很露骨。 SecurityContextPersistentFilter 接口(interface)的目的是将安全上下文存储在某个存储库中。 为完成此任务,过滤器将作业委托(delegate)给 SecurityContextRepository 接口(interface)。 Spring为此接口(interface)提供了默认实现:org.springframework.security.web.context.HttpSessionSecurityContextRepository .这是不言自明的。安全上下文的存储库只是当前用户的 HTTP session 。 下面是 SecurityContextPersistentFilter 的 XML 配置

<!-- Filter to store the Authentication object in the HTTP Session -->   
<bean id="securityContextPersistentFilter"
    class="org.springframework.security.web.context.SecurityContextPersistenceFilter">
    <property name="securityContextRepository" ref="securityContextRepository" />
</bean>


<bean id="securityContextRepository"
    class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />

LogoutFilter

LogoutFilter 负责注销当前用户并使安全上下文无效。使 HTTP session 无效的任务再次委托(delegate)给另一个参与者,即 SecurityContextLogoutHandler。

此处理程序被注入(inject)到 LogoutFilter 构造函数中:

<bean id="logoutFilter"
    class="org.springframework.security.web.authentication.logout.LogoutFilter">
    <constructor-arg value="/pages/Security/logout.html" />
    <constructor-arg>
        <list>
            <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
        </list>
    </constructor-arg>
    <property name="filterProcessesUrl" value="/j_myApplication_logout"/>
</bean>

<constructor-arg value="/pages/Security/logout.html" /> - 它定义注销页面的 URL。

SecurityContextLogoutHandler 在 <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/> 处作为构造函数参数注入(inject)

注销操作的 HTML URL 由位于 <property name="filterProcessesUrl" value="/j_myApplication_logout"/> 的 filterProcessesUrl 参数定义

资源链接:

  1. https://doanduyhai.wordpress.com/2012/01/22/spring-security-part-i-configuration-and-security-chain/
  2. https://doanduyhai.wordpress.com/2012/02/05/spring-security-part-ii-securitycontextpersistentfilter-logoutfilter/
  3. http://shazsterblog.blogspot.com/2014/02/spring-security-custom-filterchainproxy.html
  4. http://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/context/SecurityContextPersistenceFilter.html

关于java - SecurityContextLogoutHandler 的 clearAuthentication 如何不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36802557/

相关文章:

java - 从 Map<String, Map<String, Object>> 获取不正确的值

java - Spring中构造函数 Autowiring 创建更多对象

java - Spring、MVC 和重用部分模型的策略

java - Spring MVC Maven 模块

Java vector 内积

java - 找到第一个字母字符并将其替换为大写字符

使用蓝牙客户端的 Java SE 编程

java - 如何获取 Web 应用程序的上下文实例。语境?

java - 取决于环境的 Spring 接线

java - 如何在 JSP 中显示动态生成的 svg 图像(使用 Spring MVC)?