springSecurity学习之springSecurity web如何取得用户信息

web如何取得用户信息

之前说过SecurityContextHolder默认使用的是ThreadLocal来进行存储的,而且每次都会清除,但是web每次请求都会验证用户权限,这是如何做到的呢?

这是通过SecurityContextPersistenceFilter来实现的,每次请求过来都会session中来获取SecurityContext,然后设置到SecurityContextHolder中,请求结束后再清除掉

java 复制代码
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
   HttpServletRequest request = (HttpServletRequest) req;
   HttpServletResponse response = (HttpServletResponse) res;

   if (request.getAttribute(FILTER_APPLIED) != null) {
      // ensure that filter is only applied once per request
      chain.doFilter(request, response);
      return;
   }

   request.setAttribute(FILTER_APPLIED, Boolean.TRUE);


   HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,
         response);
  // 从session获取SecurityContext
   SecurityContext contextBeforeChainExecution = repo.loadContext(holder);

   try {
     // 将SecurityContext存入SecurityContextHolder
      SecurityContextHolder.setContext(contextBeforeChainExecution);

      chain.doFilter(holder.getRequest(), holder.getResponse());

   }
   finally {
      SecurityContext contextAfterChainExecution = SecurityContextHolder
            .getContext();
      // Crucial removal of SecurityContextHolder contents - do this before anything
      // else.
      SecurityContextHolder.clearContext();
     // 存储SecurityContext
      repo.saveContext(contextAfterChainExecution, holder.getRequest(),
            holder.getResponse());
      request.removeAttribute(FILTER_APPLIED);
   }
}

loadContext获取SecurityContext

使用HttpSessionSecurityContextRepository

java 复制代码
public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {
   HttpServletRequest request = requestResponseHolder.getRequest();
   HttpServletResponse response = requestResponseHolder.getResponse();
   HttpSession httpSession = request.getSession(false);
		// 从session中获取SecurityContext
   SecurityContext context = readSecurityContextFromSession(httpSession);

   if (context == null) {
      
      context = generateNewContext();

   }

   SaveToSessionResponseWrapper wrappedResponse = new SaveToSessionResponseWrapper(
         response, request, httpSession != null, context);
   requestResponseHolder.setResponse(wrappedResponse);

   return context;
}

从session中获取SecurityContext

java 复制代码
private SecurityContext readSecurityContextFromSession(HttpSession httpSession) {
   final boolean debug = logger.isDebugEnabled();

   if (httpSession == null) {
      return null;
   }

   // Session exists, so try to obtain a context from it.

   Object contextFromSession = httpSession.getAttribute(springSecurityContextKey);

   if (contextFromSession == null) {
      return null;
   }

   // Everything OK. The only non-null return from this method.

   return (SecurityContext) contextFromSession;
}

存储SecurityContext

java 复制代码
public void saveContext(SecurityContext context, HttpServletRequest request,
      HttpServletResponse response) {
   SaveContextOnUpdateOrErrorResponseWrapper responseWrapper = WebUtils
         .getNativeResponse(response,
               SaveContextOnUpdateOrErrorResponseWrapper.class);
   
   if (!responseWrapper.isContextSaved()) {
      responseWrapper.saveContext(context);
   }
}
java 复制代码
protected void saveContext(SecurityContext context) {
   final Authentication authentication = context.getAuthentication();
   HttpSession httpSession = request.getSession(false);

   // See SEC-776
   if (authentication == null || trustResolver.isAnonymous(authentication)) {

      if (httpSession != null && authBeforeExecution != null) {
         // SEC-1587 A non-anonymous context may still be in the session
         // SEC-1735 remove if the contextBeforeExecution was not anonymous
         httpSession.removeAttribute(springSecurityContextKey);
      }
      return;
   }

   if (httpSession == null) {
      httpSession = createNewSessionIfAllowed(context);
   }

   // If HttpSession exists, store current SecurityContext but only if it has
   // actually changed in this thread (see SEC-37, SEC-1307, SEC-1528)
   if (httpSession != null) {
      // We may have a new session, so check also whether the context attribute
      // is set SEC-1561
      if (contextChanged(context)
            || httpSession.getAttribute(springSecurityContextKey) == null) {
        // 存到session中
         httpSession.setAttribute(springSecurityContextKey, context);

         
      }
   }
}

https://zhhll.icu/2024/框架/springSecurity/7.web如何取得用户信息/

相关推荐
是小崔啊10 分钟前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
黄公子学安全19 分钟前
Java的基础概念(一)
java·开发语言·python
liwulin050620 分钟前
【JAVA】Tesseract-OCR截图屏幕指定区域识别0.4.2
java·开发语言·ocr
jackiendsc24 分钟前
Java的垃圾回收机制介绍、工作原理、算法及分析调优
java·开发语言·算法
Yuan_o_25 分钟前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
Oneforlove_twoforjob29 分钟前
【Java基础面试题027】Java的StringBuilder是怎么实现的?
java·开发语言
数据小小爬虫1 小时前
利用Java爬虫获取苏宁易购商品详情
java·开发语言·爬虫
小汤猿人类1 小时前
nacos-服务发现注册
java·开发语言·服务发现
码农爱java1 小时前
设计模式--抽象工厂模式【创建型模式】
java·设计模式·面试·抽象工厂模式·原理·23种设计模式·java 设计模式
2401_854391081 小时前
SSM 架构中 JAVA 网络直播带货查询系统设计与 JSP 有效实现方法
java·开发语言·架构