Springboot +spring security,实现RememberMe和实现原理分析

news2024/11/17 13:52:23

一.简介

我们在登录网站的时候,除了让你输入用户名和密码,还会有个勾选框: 记住我。
比如下面这个截图:
在这里插入图片描述
Spring Security 也提供了这个功能,今天来实践下。

二.创建项目

如何创建一个SpringSecurity项目,前面文章已经有说明了,这里就不重复写了。

三.代码实现

开启rememberMe功能,只需要简单的修改下配置即可,代码如下:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .rememberMe()
                .and()
                .csrf().disable();
        return http.build();
    }

四.实现思路

  1. 当用户登录网站后,并且勾选rememberMe
  2. 服务端认证通过,则把用户信息进行算法加密,加密完成后,通过cookie,让浏览器把cookie保存在本地
  3. 当浏览器关闭后重新打开网站,浏览器会把cookie带给服务端
  4. 服务端校验cookie确定用户身份,进而自动登录

五.源码分析

首先找切入点,我们前面讲过当引入一个新功能的时候,必定会引入一个configurer,rememberMe 也不例外:点击.rememberMe()进入源码,截图如下:
在这里插入图片描述
看到了RememberMeConfigurer,点进去看下主要是看init和configure方法。

5.1 init()方法

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);
 }
  1. getKey() 这个就是我们刚开始设置的key,如果不配置,每次系统都会重启,导致需要重新登录
  2. getRememberMeServices() 用来实现自动登录、处理登录成功和登录失败的逻辑,主要有两个继承
  3. PersistentTokenBasedRememberMeServices 持久化令牌到数据库
  4. TokenBasedRememberMeServices
  5. http.authenticationProvider(authenticationProvider);创建一个认证器放到providerList里面
  6. initDefaultLoginFilter(http); 在自定生成登录页面加上rememberMe 选框

5.2 configure()方法

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);
 }
  1. 创建了一个过滤器:RememberMeAuthenticationFilter
  2. postProcess(rememberMeFilter); 注入IOC容器
  3. 在http中加入rememberMe过滤器

看完了RememberMeConfigurer的两个核心方法之后,我们现在知道容器中已经有了RememberMeAuthenticationFilter和RememberMeAuthenticationProvider ,现在分别来看下两个的代码。

5.3RememberMeAuthenticationFilter

代码如下:

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 AuthenticationManager
   try {
    rememberMeAuth = this.authenticationManager.authenticate(rememberMeAuth);
    // Store to SecurityContextHolder
    SecurityContext 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);
 }
  1. 调用autoLogin方法
    从cookie提取用户身份,在调用loadUserByUsername获取用户详细信息
    校验用户身份是否合法(根据不同的令牌存储方式进行不同校验)
    如果校验通过,则返回Authentication(RememberMeAuthenticationToken)
  2. 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是否一致,如果一致,则校验通过。

这样就实现了RememberMe的功能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/563677.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【精】MySQL5.7没有row_number()函数如何组内排序和求分组topN

当我们遇到一些需求&#xff0c;比如组内分组排序&#xff0c;分组topN等&#xff0c;很容易想到用row_number()函数 ​在MySQL8.0版本中支持row_number函数&#xff0c;本文不做讨论&#xff0c;如果是MySQL5.7版本&#xff0c;要怎么写SQL呢&#xff1f; 测试表&#xff1a;…

Three.js教程:点、线、网格模型介绍

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 其他系列工具&#xff1a; NSDT简石数字孪生 点、线、网格模型介绍 经过前面几章学习相信你对点模型Points、线模型Line、网格模型Mesh已经有了大致了解&#xff0c;本节课就对点、线、网格模型模型进行简单总结。 点模型…

阿里大佬随手甩出一份覆盖全网的微服务架构笔记,让我涨薪60%

在这个凡事皆互联的时代&#xff0c;越来越多的人和物成为互联网上的节点&#xff0c;不断扩充着互联网这张大网的边界。节点即价值&#xff0c;更多的节点意味着更大的价值。 微服务在这个互联网时代依旧是最火热的技术之一&#xff0c;在当下互联网企业不懂微服务是不行的&a…

软件测试人员如何为项目的质量保障兜底?看完你就明白了...

上线前层层保障 01文档管理 关键词&#xff1a;需求文档、设计文档、测试文档 1.需求和设计产出方为产品、开发&#xff0c;测试需要做好流程监督&#xff0c;这里重点说下测试文档。 2.测试文档&#xff0c;从业务领域来说&#xff0c;一般有测试计划、测试用例、业务总结文…

环信新鲜出炉的 React-UIKIT 库初体验,瞬间实现即时通讯功能!

一、前言 为了加快即时通讯需求产品开发速度&#xff0c;将更多的时间放在关系核心业务逻辑的处理上&#xff0c;环信正式推出可扩展&#xff0c;易使用的 React 版本的 UIKIT 库 此 UIKit 库 是基于 环信 Web SDK 开发的的 UI 组件库&#xff0c;它提供了常用的 UI 组件、包含…

【尚好房项目实战】:第一章项目架构介绍

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 spring版本&#xff1a;5.3.1 文章目录 前言尚好房项目实战系列文章目录一、项目介绍二、核心技术点三、项目…

次氯酸消毒剂制备中的全氟醚橡胶密封耐腐蚀电动阀门解决方案

摘要&#xff1a;次氯酸作为是一种新型消毒剂&#xff0c;近年来广泛应用于医疗卫生机构、公共卫生场所和家庭的一般物体表面、医疗器械、医疗废物等。由于次氯酸的酸性和强氧化性&#xff0c;使得次氯酸生产制备过程中会给流量调节阀门带来腐蚀并影响寿命和控制精度&#xff0…

电影票房之数据分析(Hive)--第1关

电影票房之数据分析&#xff08;Hive&#xff09; 第1关&#xff1a;统计2020年上映的电影中&#xff0c;当前总票房最高的10部电影 本关任务 基于EduCoder平台提供的初始数据集&#xff0c;统计 2020 年上映的电影中&#xff0c;当前总票房最高的 10 部电影。 编程要求 本…

论文阅读:GLOBAL PROTOTYPE ENCODING FOR INCREMENTALVIDEO HIGHLIGHTS DETECTION

摘要&#xff1a; 视频亮点检测 (VHD) 是计算机视觉中的一个活跃研究领域&#xff0c;旨在在给定原始视频输入的情况下定位最吸引用户的片段。然而&#xff0c;大多数 VHD 方法都是基于封闭世界假设&#xff0c;即预先定义固定数量的高亮类别&#xff0c;并且所有训练数据都是…

IDEA刷新太慢,非得强制reload from disk

IDEA刷新太慢&#xff0c;每次 reload from disk才能最新代码咋办。 比如我用 IDEA开发代码&#xff0c;但我用github desktop 等第三方客户端软件提交代码的&#xff0c;但是 IDEA显示还是未提交的代码。此时&#xff0c;必须强制reload from disk才跟得上磁盘改变。 安装这个…

校园能耗监测管理系统是什么?有什么作用?

随着全球气候变化和环境问题的日益严重&#xff0c;校园能耗监测管理系统成为了可持续发展的重要手段。校园能耗监测管理系统可以对校园的能源使用情况进行实时监测、统计和分析&#xff0c;进而优化能源使用&#xff0c;降低能源消耗和运营成本&#xff0c;为绿色校园建设提供…

单链表相交编程题——java实现

题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xf…

抖音账号矩阵系统源码开发功能模块分析

抖音账号矩阵系统源码是一款基于PHP语言开发的混剪工具&#xff0c;可以方便地将多个抖音账号的视频素材进行混剪&#xff0c;生成一个新的视频。该工具使用了多线程、协程和异步编程等技术&#xff0c;可以显著提高处理速度&#xff0c;并且支持自动去重和自动合成背景音乐等功…

报名开源之夏,与 StarRocks 一起畅游代码的海洋!

开源之夏是由中科院软件所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动&#xff0c;旨在鼓励在校学生积极参与开源软件的开发维护&#xff0c;培养和发掘更多优秀的开发者&#xff0c;促进优秀开源软件社区的蓬勃发展&#xff0c;助力开源软件供应链建设。 202…

YOLOV5使用(一)

yolov5的工程使用(以人员检测为案例) 使用ubuntu为案例 docker run --gpus all -it -p 6007:6006 -p 8889:8888 --name my_torch -v $(pwd):/app easonbob/my_torch1-pytorch:22.03-py3-yolov5-6.0使用端口映射功能也就是说打开jupyter lab的指令是 http://localhost:8889/l…

flutter系列之:做一个下载按钮的动画

文章目录 简介定义下载的状态定义DownloadButton的属性让DownloadButton的属性可以动态变化定义downloadController定义DownloadButton的细节总结 简介 我们在app的开发过程中经常会用到一些表示进度类的动画效果&#xff0c;比如一个下载按钮&#xff0c;我们希望按钮能够动态…

AI歌手:新晋挑战者还是未来主流的替代者?

AI歌手&#xff1a;新晋挑战者还是未来主流的替代者&#xff1f; 近日&#xff0c;一款名为“AI孙燕姿”的AI歌手火遍全网&#xff0c;其翻唱的林俊杰的《她说》、周杰伦的《爱在西元前》、赵雷的《成都》等歌曲让网友纷纷表示&#xff1a;“听了一晚上&#xff0c;出不去了。…

《信息技术时代》期刊简介及投稿要求

《信息技术时代》&#xff08;半月刊&#xff09;本刊是由国家新闻总署批准&#xff0c;深圳湾科技发展有限公司主管主办的信息类期刊&#xff0c;国内统一刊号CN&#xff1a;44-1536/TN&#xff0c;国际标准刊号ISSN&#xff1a;1671-153x。本刊旨在为全集团的信息工作者提供交…

Hadoop部署完全分布式

​ 在真实的企业环境中&#xff0c;服务器集群会使用到多台机器&#xff0c;共同配合&#xff0c;来构建一个完整的分布式文件系统。而在这样的分布式文件系统中&#xff0c;HDFS相关的守护进程也会分布在不同的机器上&#xff0c;例如: NameNode守护进程&#xff0c;尽可能的…

【OpenCv • c++】几何检测 —— 霍夫变换 | 霍夫直线检测 | 霍夫线变化

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;【OpenCV • c】计算机视觉&#x1f308; 若有帮助&#xff0c;还请关注➕点赞➕收藏&#xff…