Spring Boot 2.1.5.RELEASE Spring Security 版本:5.1.5-RELEASE Spring Security 官方文档

    SecurityContextHolder 是 Spring Security 身份认证模块的核心。
    SecurityContextHolder 包含了 SecurityContext ,相关图示如下:
    image.png
    · SecurityContextHolder 是 Spring Security 用来存放用户认证后的详细信息。
    Spring Security 不关心SecurityContextHolder 如何填充。
    如果 SecurityContextHolder 包含一个值,那么 SecurityContextHolder会被用作当前经过身份验证的用户。

    表示用户已经经过验证的最简单的方法是直接设置 Authentication 。案例代码如下: image.png

    • step1、通过 SecurityContextHolder 实例化 SecurityContext 对象
    • step2、实例化 Authentication 对象(任何示例对象),并设置到 SecurityContext 中
    • step3、将 Authentication 设置到 SecurityContext 中

    当设置完后,可以通过简单的API从 SecurityContextHolder 中获取身份认证信息,案例代码如下: image.png

    SecurityContextHolder 默认使用 ThreadLocal 来存储这些信息,这意味着 SecurityContext 始终对同一线程中的方法可用,即使 SecurityCcontext 没有显示的将其作为参数传递给方法。如果在当前主体的请求被处理后小心地清除线程,那么以这种方式使用ThreadLocal 是完全安全的。而 Spring Security 中的 FilterChainProxy 确保了 SecurityContext 在请求处理完成后总是能够被清除。

    一些应用由于其线程特殊的处理方式,不适合使用 ThreadLocal 来存储这些信息。例如:Swing Client 可能需要所有的线程使用相同的线程上下文。

    SecurityContextHolder 支持策略配置在启动的时候指定使用那种方式来存储上下文信息(SecurityContext)。

    对于独立的应用可以使用 SecurityContextHolder.MODE_GLOBAL 策略MODE_INHERITABLETHREADLOCAL。

    其他应用可能希望具有安全线程派生的子线程也具备相同的 SecurityContext 上下文信息,这时候可以使用 SecurityContextHolder.MODE_INHERITABLETHREADLOCAL 策略。

    修改策略配置的方式有两种

    • 直接修改系统配置
    • 调用 SecurityContextHolder 静态方法指定(更多参考:SecurityContextHolder JavaDoc 描述)