SpringSecurity5|12.实现RememberMe 及 实现原理分析
security/day08
这个功能大家还熟悉么?我们在登录网站的时候,除了让你输入用户名和密码,还会有个勾选框:
记住我!!!不是让大家记住我哈。

值得一提的是,Spring Security 也提供了这个功能,我们今天就来体验一把。
代码实战
其实想要开启rememberMe功能,其实很简单,只需要简单的修改下配置即可:
@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests().anyRequest().authenticated().and().formLogin().permitAll().and().rememberMe().and().csrf().disable();return http.build();}
实现思路
- 当用户登录网站后,并且勾选rememberMe
- 服务端认证通过,则把用户信息进行算法加密,加密完成后,通过cookie,让浏览器把cookie保存在本地
- 当浏览器关闭后重新打开网站,浏览器会把cookie带给服务端
- 服务端校验cookie确定用户身份,进而自动登录
源码分析
首先我们找切入点,我们前面讲过当引入一个新功能的时候,必定会引入一个configurer,rememberMe 也不例外:点击.rememberMe()进入源码

看到了RememberMeConfigurer,我们点进去看下主要是看init和configure方法
init
public void init(H http) throws Exception {validateInput();String key = getKey();RememberMeServices rememberMeServices = getRememberMeServices(http, key);http.setSharedObject(RememberMeServices.class, rememberMeServices);LogoutConfigurer<H> logoutConfigurer = http.getConfigurer(LogoutConfigurer.class);if (logoutConfigurer != null && this.logoutHandler != null) {logoutConfigurer.addLogoutHandler(this.logoutHandler);}RememberMeAuthenticationProvider authenticationProvider = new RememberMeAuthenticationProvider(key);authenticationProvider = postProcess(authenticationProvider);http.authenticationProvider(authenticationProvider);initDefaultLoginFilter(http);}
- getKey() 这个就是我们刚开始设置的key,如果不配置,每次系统都会重启,导致需要重新登录
- getRememberMeServices() 用来实现自动登录、处理登录成功和登录失败的逻辑,主要有两个继承
- PersistentTokenBasedRememberMeServices 持久化令牌到数据库
- TokenBasedRememberMeServices
- http.authenticationProvider(authenticationProvider);创建一个认证器放到providerList里面
- initDefaultLoginFilter(http); 在自定生成登录页面加上rememberMe 选框
configure
public void configure(H http) {RememberMeAuthenticationFilter rememberMeFilter = new RememberMeAuthenticationFilter(http.getSharedObject(AuthenticationManager.class), this.rememberMeServices);if (this.authenticationSuccessHandler != null) {rememberMeFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler);}rememberMeFilter = postProcess(rememberMeFilter);http.addFilter(rememberMeFilter);}
- 创建了一个过滤器:RememberMeAuthenticationFilter
- postProcess(rememberMeFilter); 注入IOC容器
- 在http中加入rememberMe过滤器
看完了RememberMeConfigurer的两个核心方法之后,我们现在知道容器中已经有了RememberMeAuthenticationFilter和RememberMeAuthenticationProvider
现在分别来看下
RememberMeAuthenticationFilter
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)throws IOException, ServletException {Authentication rememberMeAuth = this.rememberMeServices.autoLogin(request, response);if (rememberMeAuth != null) {// Attempt authenticaton via AuthenticationManagertry {rememberMeAuth = this.authenticationManager.authenticate(rememberMeAuth);// Store to SecurityContextHolderSecurityContext context = SecurityContextHolder.createEmptyContext();context.setAuthentication(rememberMeAuth);SecurityContextHolder.setContext(context);onSuccessfulAuthentication(request, response, rememberMeAuth);this.securityContextRepository.saveContext(context, request, response);if (this.successHandler != null) {this.successHandler.onAuthenticationSuccess(request, response, rememberMeAuth);return;}}catch (AuthenticationException ex) {this.rememberMeServices.loginFail(request, response);onUnsuccessfulAuthentication(request, response, ex);}}chain.doFilter(request, response);}
- 调用autoLogin方法
- 从cookie提取用户身份,在调用loadUserByUsername获取用户详细信息
- 校验用户身份是否合法(根据不同的令牌存储方式进行不同校验)
- 如果校验通过,则返回Authentication(RememberMeAuthenticationToken)
- authenticate
- 如果autoLogin成功,则和前面普通登录一样进行认证
- 因为这里生成的是RememberMeAuthenticationToken,则最终会被RememberMeAuthenticationProvider处理
- 如果认证返回则进行对应的响应处理
RememberMeAuthenticationProvider
public Authentication authenticate(Authentication authentication) throws AuthenticationException {if (!supports(authentication.getClass())) {return null;}if (this.key.hashCode() != ((RememberMeAuthenticationToken) authentication).getKeyHash()) {throw new BadCredentialsException(this.messages.getMessage("RememberMeAuthenticationProvider.incorrectKey","The presented RememberMeAuthenticationToken does not contain the expected key"));}return authentication;}
这里的逻辑只做了一步,校验key的hashCode是否一致,如果一致,则校验通过
相关文章:
SpringSecurity5|12.实现RememberMe 及 实现原理分析
security/day08 这个功能大家还熟悉么?我们在登录网站的时候,除了让你输入用户名和密码,还会有个勾选框: 记住我!!!不是让大家记住我哈。 值得一提的是,Spring Security 也提供了这个…...
持续集成交付CICD:Jenkins Sharedlibrary 共享库
目录 一、理论 1.共享库 2.共享库配置 3.使用共享库 4.共享库扩展 二、实验 1.连接共享库 2.使用共享库 三、问题 1.路径报错 2.readJSON 报错 一、理论 1.共享库 (1)概念 1)共享库这并不是一个全新的概念,其实在编…...
Linux--网络编程
一、网络编程概述1.进程间通信: 1)进程间通信的方式有**:管道,消息队列,共享内存,信号,信号量这么集中 2)特点:依赖于linux内核,基本是通过内核来实现应用层…...
数据结构 并查集
作用 快速的处理以下问题:【近乎O(1)的时间完成】 1.将两个集合合并 2.询问两个元素是否在一个集合中 用树的形式维护集合 基本原理 每一个集合用一棵树表示 每一个集合的编号就是根结点的编号,对于每一个结点,都存储其父结点…...
算法通关村第十六关黄金挑战——求滑动窗口中的最大值(滑动窗口与堆方法、双端队列法和直接比较法)
大家好,我是怒码少年小码。 今天这篇就讲一道题目,不难😎,但是一定要学会自己思考。 滑动窗口最大值 LeetCode 239:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。…...
常见树种(贵州省):009楠木、樟木、桂木种类
摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、楠木 …...
全志H616开发版
开发板介绍: 二、开发板刷机 SDFormatter TF卡的格式化工具、Win32Diskimager 刷机工具 刷机镜像为:Orangepizero2_2.2.0_ubuntu_bionic_desktop_linux4.9.170.img 使用MobaXterm_Personal_20.3连接使用 网络配置:nmcli dev wifi 命令接入网…...
【Spring boot】RedisTemplate中String、Hash、List设置过期时间
文章目录 前言Redis中String设置时间的方法Redis中Hash和List设置时间的方法Redis中Hash的put、putAll、putIfAbsent区别 前言 时间类型:TimeUnit import java.util.concurrent.TimeUnit;TimeUnit.SECONDS:秒 TimeUnit.MINUTES:分 TimeUnit.HOURS&…...
Nosql之redis概述及基本操作
关系数据库与非关系型数据库概述 关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型…...
使ros1和ros2的bag一直互通
很多文章都是先source ros1 然后source ros2,再play bag source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash ros2 bag play -s rosbag_v2 kitti_raw00.bag 但实测会出问题: 为使ros1和ros2的bag一直互通 sudo apt update sudo apt install ros-foxy-ro…...
【正点原子 linux 驱动编程】
在此声明,正用点编的说明书真的拉,丝毫不具备兼容性。。比如linux的第一个实验,其中包含的 unregister_chrdev_region 函数,fileoperation 结构体等均来自 <linux/fs.h> 文件,搞不懂,他们方ide.h&…...
使用Python的turtle模块绘制玫瑰花图案(含详细Python代码与注释)
1.1引言 turtle模块是Python的标准库之一,它提供了一个绘图板,让我们可以在屏幕上绘制各种图形。通过使用turtle,我们可以创建花朵、叶子、复杂的图案等等。本博客将介绍如何使用turtle模块实现绘制图形的过程,并展示最终结果。 …...
Redis学习笔记14:基于spring data redis及lua脚本ZSET有序集合实现环形结构案例及lua脚本如何发送到redis服务器
案例实现目标,一、实现一个环形结构,环形结构上节点有一个阀值threshold,超过阀值则移除分数score最低的成员,不足则将当前成员添加进环中,且确保成员不可重复;二、每次访问环中的数据都需要刷新key的过期时间…...
openssl C++研发之pem格式处理详解
一、PEM_writeXXX和EM_write_bio_XXX 在OpenSSL的crypto/pem.h头文件中,PEM_write_XXXX和PEM_write_bio_XXXX系列函数用于将特定类型的数据写入文件或BIO(内存缓冲区)中,其中XXXX代表不同的数据类型。 这些函数的使用方式相似&a…...
【教3妹学编辑-mysql】详解数据库三大范式
什么是范式 简单地理解就是:数据库设计时遵循的规范 三大范式 数据库三大范式包含:1、第一范式(1NF);2、第二范式(2NF);3、第三范式(3NF)。其中,第一范式(1NF)的要求是属性不可分割,第二范式(2NF)的要求是…...
【计算机网络笔记】路由算法之链路状态路由算法
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...
读像火箭科学家一样思考笔记04_第一性原理(下)
1. 来自无形规则的阻力 1.1. 无形规则 1.1.1. 僵化成规则的不必要习惯和行为 1.1.2. 不像有形的书面规则 1.1.2.1. 书面规则出现在标准操作流程中,可以修改或删除 1.1.3. 成文的规则可能会抗拒变革,但无形规则却更加顽固 1.1.4. 我们为强加在自己身…...
开源集群管理系统对比分析:Kubernetes 与 Apache Mesos
集群管理系统是关键的软件解决方案,可以在互连机器网络中有效分配和利用计算资源。毫无疑问,它们通过确保可扩展性、高可用性和有效的资源管理在现代计算中发挥着至关重要的作用,这使得它们对于运行复杂的应用程序、管理数据中心以及进一步增…...
matlab 坡度滤波算法地面分割
目录 一、算法原理1、实现流程2、参考文献二、代码实现三、结果展示四、测试数据一、算法原理 1、实现流程 1、格网示意图 2、计算格网行列数 公式中的特殊符号为向上取整,...
【腾讯云 HAI域探秘】高性能服务器引领AI革新浪潮:从AI绘画、知识问答到PyTorch图像分类、视频检测的全方位探索
目录 1 HAI(高性能应用服务)简介2 HAI的应用场景2.1 HAI在AI作画中的灵活性与效率2.2 深入探索LLM语言模型的应用与性能2.3 HAI支持的AI模型开发环境与工具 3 基于stable difussio的AI 绘画应用实践3.1 使用AI模型中的stable diffusion模型服务3.2 设置和…...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
