当前位置: 首页 > news >正文

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

web如何取得用户信息

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

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

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 requestchain.doFilter(request, response);return;}request.setAttribute(FILTER_APPLIED, Boolean.TRUE);HttpRequestResponseHolder holder = new HttpRequestResponseHolder(request,response);// 从session获取SecurityContextSecurityContext contextBeforeChainExecution = repo.loadContext(holder);try {// 将SecurityContext存入SecurityContextHolderSecurityContextHolder.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();// 存储SecurityContextrepo.saveContext(contextAfterChainExecution, holder.getRequest(),holder.getResponse());request.removeAttribute(FILTER_APPLIED);}
}

loadContext获取SecurityContext

使用HttpSessionSecurityContextRepository

public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) {HttpServletRequest request = requestResponseHolder.getRequest();HttpServletResponse response = requestResponseHolder.getResponse();HttpSession httpSession = request.getSession(false);// 从session中获取SecurityContextSecurityContext context = readSecurityContextFromSession(httpSession);if (context == null) {context = generateNewContext();}SaveToSessionResponseWrapper wrappedResponse = new SaveToSessionResponseWrapper(response, request, httpSession != null, context);requestResponseHolder.setResponse(wrappedResponse);return context;
}

从session中获取SecurityContext

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

public void saveContext(SecurityContext context, HttpServletRequest request,HttpServletResponse response) {SaveContextOnUpdateOrErrorResponseWrapper responseWrapper = WebUtils.getNativeResponse(response,SaveContextOnUpdateOrErrorResponseWrapper.class);if (!responseWrapper.isContextSaved()) {responseWrapper.saveContext(context);}
}
protected void saveContext(SecurityContext context) {final Authentication authentication = context.getAuthentication();HttpSession httpSession = request.getSession(false);// See SEC-776if (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 anonymoushttpSession.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-1561if (contextChanged(context)|| httpSession.getAttribute(springSecurityContextKey) == null) {// 存到session中httpSession.setAttribute(springSecurityContextKey, context);}}
}

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

http://www.lryc.cn/news/405457.html

相关文章:

  • eclipse中的classbean导入外部class文件,clean项目后删除问题
  • OBD诊断(ISO15031) 0A服务
  • ForCloud全栈安全体验,一站式云安全托管试用 开启全能高效攻防
  • Java——————接口(interface) <详解>
  • 【C++】【继承】【子对象】【构造函数】含子对象的派生类的构造函数写法
  • golang语言 .go文件版本条件编译,xxx.go文件指定go的编译版本必须大于等于xxx才生效的方法, 同一个项目多个go版本文件共存方法
  • 深入浅出mediasoup—通信框架
  • 每日一题 LeetCode03 无重复字符的最长字串
  • 栈和队列(C语言)
  • swagger-ui.html报错404
  • Milvus 核心组件(3)--- MinIO详解
  • [数据集][目标检测]婴儿车检测数据集VOC+YOLO格式1073张5类别
  • JAVASE进阶day14(网络编程续TCP,日志)
  • 机器学习(五) -- 无监督学习(1) --聚类1
  • leetcode 116. 填充每个节点的下一个右侧节点指针
  • [C++]优先级队列
  • 学习大数据DAY22 Linux 基 本 指 令 3与 在 Linux 系 统 中 配 置MySQL 和 Oracle
  • scp 服务器复制命令
  • PyQt5学习路线
  • 2024论文精读:利用大语言模型(GPT)增强上下文学习去做关系抽取任务
  • WEB 手柄 http通信,mcu端解析代码 2024/7/23 日志
  • cmake中的正则表达式
  • 05. Java 三大范式
  • opencv 按键开启连续截图,并加载提示图片
  • Android-- 集成谷歌地图
  • Jvm是如何处理异常的
  • recursion depth exceeded” error
  • 虚拟现实和增强现实技术系列—Expressive Talking Avatars
  • 网站验证:确保网络安全与信任的重要步骤
  • C语言——字符串比较函数strcmp和strncmp