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

相关推荐
Freak嵌入式15 分钟前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
java·开发语言·数据结构·python·接口·抽象基类
前端小马25 分钟前
解决IDEA出现:java: 程序包javax.servlet不存在的问题
java·servlet·intellij-idea
IH_LZH1 小时前
Broadcast:Android中实现组件及进程间通信
android·java·android studio·broadcast
去看全世界的云1 小时前
【Android】Handler用法及原理解析
android·java
.Net Core 爱好者1 小时前
Redis实践之缓存:设置缓存过期策略
java·redis·缓存·c#·.net
晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑1 小时前
苍穹外卖学习笔记(五)
java·笔记·学习
码上一元1 小时前
【百日算法计划】:每日一题,见证成长(017)
java·算法
用生命在耍帅ㅤ1 小时前
java spring boot 动态添加 cron(表达式)任务、动态添加停止单个cron任务
java·开发语言·spring boot
学java的小菜鸟啊1 小时前
第五章 网络编程 TCP/UDP/Socket
java·开发语言·网络·数据结构·网络协议·tcp/ip·udp
zheeez2 小时前
微服务注册中⼼2
java·微服务·nacos·架构