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

Spring Security 6.x 系列(6)—— 显式设置和修改登录态信息

一、前言

此篇是对上篇 Spring Security 6.x 系列(5)—— Servlet 认证体系结构介绍 中4.9章节显式调用SecurityContextRepository#saveContext进行详解分析。

二、设置和修改登录态

2.1 登录态存储形式

使用Spring Security框架,认证成功后的用户信息会放在Authentication对象的Principal中,
Authentication对象又会被放入SecurityContext中,而SecurityContext 存在这2个地方:

  • SecurityContextHolderStrategy :线程级别的SecurityContext持有策略。有全局共享、线程继承、线程隔离等几种获取上下文的方式(上文有过介绍)。

  • SecurityContextRepository:持久化SecurityContext ,默认存入HttpServletRequestHttpSession

在代码中,我们要获取用户登录信息,可以通过SecurityContextHolder.getContext().getAuthentication()的方式获取,这种方式是从SecurityContextHolderStrategy获取用户数据。而SecurityContextHolderStrategy初始化数据又是来自SecurityContextRepository,相关逻辑是在SecurityContextHolderFilter类里。

SecurityContextHolderFilter#doFilter源码如下:

在这里插入图片描述
查看securityContextRepository如下:

在这里插入图片描述

设想一种场景,在用户登录后,编辑了用户信息,这时要同步刷新SecurityContext里的用户信息。我们要如何更新这两个处的用户数据呢?

2.2 更新SecurityContextHolderStrategy中的用户信息

要更新SecurityContextHolderStrategy非常简单,因为它保存在内存里,只要通过SecurityContextHolder.getContext().getAuthentication() 获取认证信息后,直接设置对应的属性,内存中属性值发生变化,后续处理逻辑就能读到最新值。

Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
MyUser myUser = (MyUser) authentication.getPrincipal();
myUser.setNickname("新的昵称");

2.3 更新SecurityContextRepository中的用户信息

2.3.1 了解SecurityContextRepository接口

SecurityContextRepository是一个接口,源码如下:

public interface SecurityContextRepository {/** @deprecated */@DeprecatedSecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder);default DeferredSecurityContext loadDeferredContext(HttpServletRequest request) {Supplier<SecurityContext> supplier = () -> {return this.loadContext(new HttpRequestResponseHolder(request, (HttpServletResponse)null));};return new SupplierDeferredSecurityContext(SingletonSupplier.of(supplier), SecurityContextHolder.getContextHolderStrategy());}void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response);boolean containsContext(HttpServletRequest request);
}

SecurityContextRepository接口有以下几个实现类:

  • NullSecurityContextRepository:什么都不做,也就是不会存储,每次请求都需要重新认证
  • HttpSessionSecurityContextRepository:将SecurityContext保存在Session中,获取的时候,从Session中查询
  • RequestAttributeSecurityContextRepository:将SecurityContext保存在请求对象HttpServletRequest
  • DelegatingSecurityContextRepository:委派代理存储,内部维护多个SecurityContextRepository,实现同时支持多种方式存储SecurityContext

2.3.2 无法直接获取SecurityContextRepository对象

要知道怎么更新SecurityContextRepository ,我们先看其他地方是怎么调用它。往SecurityContextRepository写数据是在用户认证成功之后,调用AbstractAuthenticationProcessingFilter#successfulAuthentication() 方法,执行认证成功的后续逻辑时。

在这里插入图片描述
在这里插入图片描述

这里的this.securityContextRepository是通过setter方法传进来的,并且发现Spring Security没有把SecurityContextRepository注册到Spring容器,而且Spring Security其他持有SecurityContextRepository对象的类都没有暴露SecurityContextRepository的获取方法。也就是说,我们无法从Spring Security拿到默认的SecurityContextRepository对象。

debug发现this.securityContextRepository属性指向了 DelegatingSecurityContextRepository,这是委派代理存储,代理的对象是 RequestAttributeSecurityContextRepositoryHttpSessionSecurityContextRepository,所以在默认的情况下,用户登录成功之后,在这里就把登录用户数据分别存入到HttpSessionSecurityContextRepositoryRequestAttributeSecurityContextRepository中。

在这里插入图片描述

部分DelegatingSecurityContextRepository源码如下:

在这里插入图片描述
在这里插入图片描述

2.3.3 手动设置SecurityContextRepository对象

为了顺利拿到SecurityContextRepository对象,我们可以手动往Spring容器注册一个SecurityContextRepository对象,然后把它塞到Spring Security里。通过这种方式,我们能从Spring容器拿到SecurityContextRepository 对象,然后随时刷新SecurityContext

具体实现代码如下:

@Bean
public SecurityContextRepository securityContextRepository() {return new DelegatingSecurityContextRepository(new RequestAttributeSecurityContextRepository(), new HttpSessionSecurityContextRepository());
}@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity, SecurityContextRepository securityContextRepository) throws Exception {httpSecurity.securityContext((context) -> context.securityContextRepository(securityContextRepository()));
}

这里DelegatingSecurityContextRepositorySpring Security中的SecurityContextRepository默认实现,我们原封不动保留下来。

2.3.4 更新登录态

在更新完SecurityContextHolderStrategy 对象之后,我们显式把SecurityContext重新保存到SecurityContextRepository

// 更新SecurityContextHolderStrategy
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
MyUser myUser = (MyUser) authentication.getPrincipal();
myUser.setNickname("新的昵称");// 更新SecurityContextRepository
securityContextRepository.saveContext(SecurityContextHolder.getContext(), request, response);

三、总结

通过显式更新SecurityContextHolderStrategySecurityContextRepository ,我们就能完整更新SecurityContext 中的用户信息。如果项目中引入了Spring SessionSpring Session维护的登录态也会同步更新。

相关文章:

Spring Security 6.x 系列(6)—— 显式设置和修改登录态信息

一、前言 此篇是对上篇 Spring Security 6.x 系列&#xff08;5&#xff09;—— Servlet 认证体系结构介绍 中4.9章节显式调用SecurityContextRepository#saveContext进行详解分析。 二、设置和修改登录态 2.1 登录态存储形式 使用Spring Security框架&#xff0c;认证成功…...

Linux的软件安装

Linux的软件安装 1、rpm软件安装包 RPM&#xff08;RedHat Package Manager&#xff09;安装管理 ​ 这个机制最早是由Red Hat开发出来,后来实在很好用,因此很多 distributions&#xff08;发行版&#xff09;就使用这个机制来作为软件安装的管理方式 。包括Fedora,CentOS,S…...

443. 压缩字符串

这篇文章会收录到 : 算法通关村第十二关-黄金挑战字符串冲刺题-CSDN博客 压缩字符串 描述 : 给你一个字符数组 chars &#xff0c;请使用下述算法压缩&#xff1a; 从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 &#xff1a; 如果这一组长度为 1 &#xff0c;…...

Python面经【6】

Python面经【6】 一、什么是Python的自省机制二、关于Python程序的运行方面&#xff0c;有什么手段可以提升性能三、dict的item()和iteritems()的不同四、说明一个os.path和sys.path分别代表什么五、说一下字典和json的区别六、什么是可变、不可变类型 一、什么是Python的自省机…...

2020年6月9日 Go生态洞察:VS Code Go扩展加入Go项目

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

C语言错误处理之“非局部跳转<setjmp.h>头文件”

目录 前言 setjmp宏 longjmp函数 使用方法&#xff1a; 实例&#xff1a;测试setjmp与longjmp的使用 前言 通常情况下&#xff0c;函数会返回到它被调用的位置&#xff0c;我们无法使用goto语句改变它的返回的方向&#xff0c;因为goto语句只能跳转到同一函数内的某个标号…...

【SpringCloud】微服务架构设计模式

一、聚合气微服务设计模式 最常见、最简单的设计模式&#xff0c;效果如图所示&#xff1a; 聚合器调用多个服务实现应用程序所需的功能 它可以是一个简单的 Web 页面&#xff0c;将检索到的数据进行处理并展示&#xff0c;也可以是一个更高层次的组合微服务&#xff0c;对…...

【EI会议征稿】第三届航空航天工程与系统国际研讨会(ISAES 2024)

第三届航空航天工程与系统国际研讨会(ISAES 2024) 2024 3rd International Symposium on Aerospace Engineering and Systems 第三届航空航天工程与系统国际研讨会将于2024年3月22-24日在南京召开&#xff01;会议紧密聚焦“航空航天工程”领域的热点和难点问题&#xff0c;…...

唯创知音WT588F02A-16S录音语音芯片在宠物喂食器中的应用:小芯片,大功能

在现代社会中&#xff0c;宠物已经成为人们生活中的一部分&#xff0c;而宠物喂食器作为宠物养护的重要工具&#xff0c;也越来越受到人们的关注。为了满足人们对宠物喂食器的多样化需求&#xff0c;唯创知音的WT588F02A-16S录音芯片在其中发挥着重要作用。 唯创知音的WT588F0…...

SELinux零知识学习三十七、SELinux策略语言之约束(1)

接前一篇文章:SELinux零知识学习三十六、SELinux策略语言之角色和用户(7) 四、SELinux策略语言之约束 SELinux对策略允许的访问提供了更严格的约束机制,不管策略的allow规则如何。 1. 近距离查看访问决定算法 为了理解约束的用途,先来看一下SELinux Linux安全模块(Lin…...

sqli-labs靶场详解(less25/25a-less28/28a)

在SQL注入过程中难点就是判断注入点 只要注入点确定了 获取数据库数据的过程就是复制 从这关开始 只进行判断注入点了和代码逻辑分析了 因为注入操作太简单了&#xff08;不演示了&#xff09; 目录 less-25 less-25a less-26 less-26a less-27 less-27a less-28 less-…...

如何优化 Elasticsearch 查询性能

优化 Elasticsearch 查询性能需要从多个方面入手。通过合理的索引设计、优化查询语句、优化硬件资源和集群架构等方面的优化&#xff0c;可以显著提高 Elasticsearch 的查询性能。 1.索引设计优化 良好的索引设计是优化 Elasticsearch 查询性能的关键。可以通过以下几个方面来…...

成功的蓝图:实现长期成长与卓越表现的 6 项策略

能在收入和利润上持续领先同行的公司寥寥无几&#xff0c;不到四分之一。McKinsey的最新研究揭示了这些增长标杆公司与众不同的六大心态和策略。过度谨慎的公司&#xff0c;尤其在动荡时期&#xff0c;也许能捱过当下&#xff0c;但往往无法发掘全部潜力。考虑到近五年历经前所…...

【JavaEE初阶】认识线程、创建线程

1. 认识线程&#xff08;Thread&#xff09; 1.1 概念 1) 线程是什么 一个线程就是一个 "执行流". 每个线程之间都可以按照顺序执行自己的代码. 多个线程之间 "同时" 执行着多份代码. 举例&#xff1a; 还是回到我们之前的银⾏的例⼦中。之前我们主要描…...

uniapp中uni.navigateBack返回后刷新页面数据

文章目录 一、前言1.1、[uni.navigateBack](https://uniapp.dcloud.net.cn/api/router.html#navigateback) 二、方法2.1、父页面设置钩子函数onBackPress2.2、uni.$emit和uni.$on监听通知数据变更2.2.1、子页面2.2.2、父页面 2.3、onShow钩子函数处理数据2.3.1、子页面2.3.2、父…...

sed文本 免交互

目录 什么是sed 概念 格式 基本用法 命令的选项 打印第三行 打印日志文件 打印奇数行 打印偶数行 第三行退出 删除第三行 sed在不打开文件的情况下修改文件内容 在后面添加 选项a 在字符中间添加 \n 实现追加换行 全部追加 在前面插入 选项i 替换 选项c …...

轻巧高效的剃须好工具,DOCO黑刃电动剃须刀上手

剃须刀大家都用过&#xff0c;我比较喜欢电动剃须刀&#xff0c;尤其是多刀头的悬浮剃须刀&#xff0c;感觉用起来很方便&#xff0c;剃须效率也很高。最近我在用一款DOCO小蔻的黑刃电动剃须刀&#xff0c;这款剃须刀轻巧易用&#xff0c;而且性价比超高。 相比于同类产品&…...

第15关 K8s HPA:自动水平伸缩Pod,实现弹性扩展和资源优化

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维&#xff0c;这节课带来k8s的HPA 自动水平伸缩pod&#xff08; 视频后面有彩蛋 : ) &#xff09;。 我们知道&#xff0c;初始Pod的数量是可以设置的&#xff0c;同时业务也分流量高峰和低峰&a…...

接口测试工具(Jmeter)必学技巧

安装 使用JMeter的前提需要安装JDK&#xff0c;需要JDK1.7以上版本 目前在用的是JMeter5.2版本&#xff0c;大家可自行下载解压使用 运行 进入解压路径如E: \apache-jmeter-5.2\bin&#xff0c;双击jmeter.bat启动运行 启动后默认为英文版本&#xff0c;可通过Options – Choos…...

C++面试,说明const和#define的特点和区别

#define只是用来做文本替换的&#xff0c;例如&#xff1a; #define PI 3.1415926 float angel; angel 30 * PI /180; 当程序进行编译的时候。编译器会首先将"#define PI 3.1415926"以后所有代码中的PI都替换成3.1415926&#xff0c;然后进行编译。它的生命周期止…...

Proteus单片机仿真与Qwen3.5-9B-AWQ-4bit联合调试:智能硬件开发新范式

Proteus单片机仿真与Qwen3.5-9B-AWQ-4bit联合调试&#xff1a;智能硬件开发新范式 1. 嵌入式开发的新机遇 传统单片机开发过程中&#xff0c;工程师们常常面临一个困境&#xff1a;硬件调试周期长、问题定位困难、代码优化依赖经验。Proteus作为成熟的电路仿真平台&#xff0…...

从零开始:基于TensorFlow和卷积神经网络的交通标志识别实战指南

1. 环境配置与工具安装 第一次接触深度学习项目时&#xff0c;环境配置往往是最让人头疼的环节。记得我刚开始做图像识别项目时&#xff0c;光是配环境就折腾了两天。现在回想起来&#xff0c;其实只要掌握正确的方法&#xff0c;整个过程可以非常顺畅。 对于交通标志识别项目&…...

别再死记硬背‘电角度=机械角度*极对数’了!用Python模拟一个7对极无刷电机,带你直观理解FOC核心概念

用Python模拟7对极无刷电机&#xff1a;从代码透视FOC核心公式的本质 当你第一次在FOC控制文档中看到"电角度机械角度极对数"这个公式时&#xff0c;是否也曾困惑于它背后的物理意义&#xff1f;传统教材往往直接抛出这个定义&#xff0c;却很少解释为什么多极电机中…...

告别Appium!用这5个AI视觉自动化工具,让你的手机脚本不再怕App更新

告别Appium&#xff01;5个AI视觉自动化工具重塑手机脚本开发 每次应用更新后&#xff0c;那些精心编写的自动化测试脚本突然失效的场景&#xff0c;测试工程师们再熟悉不过了。传统基于元素定位的工具如Appium&#xff0c;让团队陷入无休止的脚本维护泥潭。而今天&#xff0c;…...

Krita AI绘画插件终极指南:从零开始掌握AI图像生成艺术

Krita AI绘画插件终极指南&#xff1a;从零开始掌握AI图像生成艺术 【免费下载链接】krita-ai-diffusion Streamlined interface for generating images with AI in Krita. Inpaint and outpaint with optional text prompt, no tweaking required. 项目地址: https://gitcod…...

JetBrains IDE试用期重置终极指南:30天免费试用无限续杯

JetBrains IDE试用期重置终极指南&#xff1a;30天免费试用无限续杯 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 还在为JetBrains IDE试用期到期而烦恼吗&#xff1f;IDE Eval Resetter插件为你提供完美的解决…...

M5146-C2234E-250BG压力传感器测量误差如何补偿

M5146-C2234E-250BG压力传感器主要有偏移误差、灵敏度误差、线性误差和延迟误差&#xff0c;合理地进行压力传感器的误差补偿是应用的核心。由于这种差异&#xff0c;必须能够最大限度地补偿M5146-C2234E-250BG压力传感器的测量误差。这是确保传感器满足设计和应用要求的重要一…...

如何理解InnoDB的行级锁_记录锁与间隙锁Gap Lock的区别

Record Lock锁存在行&#xff0c;Gap Lock锁不存在的索引间隙&#xff1b;前者为点锁&#xff0c;后者为段锁&#xff0c;仅在REPEATABLE READ生效&#xff0c;Next-Key Lock是其与记录锁组合&#xff0c;用于防止幻读。Record Lock 锁的是“存在的行”&#xff0c;Gap Lock 锁…...

绕过喜马拉雅反爬?聊聊xm-sign签名机制的设计与合规数据获取方案

从商业视角解析xm-sign签名机制的设计逻辑与合规数据获取路径 在数字内容产业快速发展的今天&#xff0c;音频平台面临着数据保护与开放共享的双重挑战。喜马拉雅引入的xm-sign签名机制&#xff0c;正是这一背景下平台安全策略的典型代表。作为产品经理或开发者&#xff0c;理解…...

探索正点原子7寸RGB液晶屏:AD20工程实战

适用于正点原子7寸RGB液晶屏资料&#xff0c;包含AD20完整工程最近&#xff0c;我入手了一块正点原子的7寸RGB液晶屏&#xff0c;搭配AD20开发板&#xff0c;想着能折腾出点有意思的东西。折腾的过程虽然有点坎坷&#xff0c;但收获还是挺多的&#xff0c;现在就来分享一下我的…...