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

相关推荐
Bug退退退12329 分钟前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq
小皮侠30 分钟前
nginx的使用
java·运维·服务器·前端·git·nginx·github
Zz_waiting.41 分钟前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象
全栈凯哥41 分钟前
02.SpringBoot常用Utils工具类详解
java·spring boot·后端
兮动人1 小时前
获取终端外网IP地址
java·网络·网络协议·tcp/ip·获取终端外网ip地址
呆呆的小鳄鱼1 小时前
cin,cin.get()等异同点[面试题系列]
java·算法·面试
独立开阀者_FwtCoder1 小时前
"页面白屏了?别慌!前端工程师必备的排查技巧和面试攻略"
java·前端·javascript
Touper.1 小时前
JavaSE -- 泛型详细介绍
java·开发语言·算法
静若繁花_jingjing1 小时前
Redis线程模型
java·数据库·redis
hello早上好2 小时前
CGLIB代理核心原理
java·spring