SecurityContextHolder.getContext().getAuthentication() 线程安全吗?

今天想到昨天 token 的一个问题,如果 token 失效,我们需要生成新的 token 那必然需要一些登录用户的信息去构建我们的 jwt token , 我当时的想法是虽然 token 失效但是在 springSecurity 的上下文对象中存储着用户已经 登录认证过的 Authentication ,通过 Authentication 可以获取 UserDetials 信息,但是我今天早上起来想到,这只是在我单用户那必然是可以获取到我已经认证的 Authentication ,但在 web环境下,如果多个用户那会不造成 Authentication 信息紊乱的问题,虽然我感觉这不可能,人家spring 肯定会有对应的策略对此进行解决,但是具体的方法我不知道,刚在网上看了下才发现知道了,Spring Securitty 通过 ThreadLocal 来存储 SecurityContext 对象 ,通过 SecurityContext 就可以获取到 Authentication 。

核心方法:SecurityContextHolder.getContext().getAuthentication()

SecurityContextHolder 方法
SecurityContextHolder.getContext().getAuthentication() 线程安全吗?_第1张图片

/**
 *	Associates a given {@link SecurityContext} with the current execution thread. 
 *  这是源码里面的一句文档注释,意思为 : 将给定的SecurityContext与当前执行线程相关联。
 */
public class SecurityContextHolder {
   // ~ Static fields/initializers
   // =====================================================================================
   public static final String MODE_THREADLOCAL = "MODE_THREADLOCAL";
   public static final String MODE_INHERITABLETHREADLOCAL = "MODE_INHERITABLETHREADLOCAL";
   public static final String MODE_GLOBAL = "MODE_GLOBAL";
   public static final String SYSTEM_PROPERTY = "spring.security.strategy";
   private static String strategyName = System.getProperty(SYSTEM_PROPERTY);
   private static SecurityContextHolderStrategy strategy;
   private static int initializeCount = 0;

   static {
      initialize();
   }

   // ~ Methods
   // ========================================================================================================

  	/**
	 * Obtain the current SecurityContext.	
	 *
	 * @return the security context (never null)
	 */
	public static SecurityContext getContext() {
		return strategy.getContext();
	}

SecurityContextHolder利用了一个SecurityContextHolderStrategy(存储策略)进行上下文的存储。我们来看看SecurityContestHolderStrategy

SecurityContextHolderStrategy
在这里插入图片描述
SecurityContextHolder.getContext().getAuthentication() 线程安全吗?_第2张图片
由上面的类图可以以得知,这三种实现类做的是相同的事,主要区别就是存放 SecurityContext 的方式不同而已

ThreadLocalSecurityContextHolderStrategy

/**
 * A ThreadLocal-based implementation of
 * {@link SecurityContextHolderStrategy}.						基于ThreadLocal的SecurityContextHolderStrategy实现
 *
 * @author Ben Alex
 *
 * @see java.lang.ThreadLocal
 * @see org.springframework.security.core.context.web.SecurityContextPersistenceFilter
 */
final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {

   // 用来保存安全上下文对象 SecurityContext ThreadLocal
   private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>();

   public SecurityContext getContext() {
      SecurityContext ctx = contextHolder.get();

      if (ctx == null) {
         ctx = createEmptyContext();
         contextHolder.set(ctx);
      }

      return ctx;
   }

GlobalSecurityContextHolderStrategy

/**
 * A static field-based implementation of 		基于static的SecurityContextHolderStrategy实现
 * {@link SecurityContextHolderStrategy}.
 */
final class GlobalSecurityContextHolderStrategy implements SecurityContextHolderStrategy {
   // ~ Static fields/initializers
   // =====================================================================================

   private static SecurityContext contextHolder;

InheritableThreadLocalSecurityContextHolderStrategy

/**
 * An InheritableThreadLocal-based implementation of			基于InheritableThreadLocal的SecurityContextHolderStrategy实现
 * {@link org.springframework.security.core.context.SecurityContextHolderStrategy}.
 */
final class InheritableThreadLocalSecurityContextHolderStrategy implements
      SecurityContextHolderStrategy {
   // ~ Static fields/initializers
   // =====================================================================================

   private static final ThreadLocal<SecurityContext> contextHolder = new InheritableThreadLocal<>();

参考文章

添加链接描述

添加链接描述

ThreadLocal的讲解

你可能感兴趣的:(Spring,Security,spring,boot,spring,security,安全,threadlocal)