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如何取得用户信息/

相关推荐
奔跑吧邓邓子4 分钟前
【Java实战㉞】从0到1:Spring Boot Web开发与接口设计实战
java·spring boot·实战·web开发·接口设计
专注API从业者13 分钟前
Python/Java 代码示例:手把手教程调用 1688 API 获取商品详情实时数据
java·linux·数据库·python
奔跑吧邓邓子34 分钟前
【Java实战㉝】Spring Boot实战:从入门到自动配置的进阶之路
java·spring boot·实战·自动配置
ONLYOFFICE34 分钟前
【技术教程】如何将ONLYOFFICE文档集成到使用Spring Boot框架编写的Java Web应用程序中
java·spring boot·编辑器
叫我阿柒啊42 分钟前
Java全栈开发工程师的实战面试经历:从基础到微服务
java·微服务·typescript·vue·springboot·前端开发·后端开发
cyforkk1 小时前
Spring 异常处理器:从混乱到有序,优雅处理所有异常
java·后端·spring·mvc
生擒小朵拉1 小时前
STM32添加库函数
java·javascript·stm32
Z_z在努力1 小时前
【杂类】Spring 自动装配原理
java·spring·mybatis
小小菜鸡ing2 小时前
pymysql
java·服务器·数据库
getapi2 小时前
shareId 的产生与传递链路
java