Spring Security登录的简单解析

Spring Security登录的简单解析

        • 1.自己写的登录
        • 2.进入`authenticationManager.authenticate(authenticationToken);`
        • 3 进入`result = provider.authenticate(authentication);`
        • 4 进入` user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);`
        • 5 进入 `UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);`
        • 注:

1.自己写的登录
    public TokenVo login(String username, String password) {//封装 AuthenticationUsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);//认证用户Authentication authenticate = authenticationManager.authenticate(authenticationToken);if (authenticate == null) {throw new RuntimeException("认证失败!");}//获取认证用户信息UserDetailsInfo userDetailsInfo = (UserDetailsInfo) authenticate.getPrincipal();//认证通过,生成jwtTokenVo tokenVo=new TokenVo();String token = jwtTokenUtil.generateToken(userDetailsInfo);tokenVo.setToken(token);tokenVo.setExpireTime(jwtTokenUtil.expiration);redisCache.setCacheObject(token, userDetailsInfo, jwtTokenUtil.expiration, TimeUnit.SECONDS);return tokenVo;}
2.进入authenticationManager.authenticate(authenticationToken);

其所属类是ProviderManager implements AuthenticationManage

public Authentication authenticate(Authentication authentication) throws AuthenticationException {Class<? extends Authentication> toTest = authentication.getClass();AuthenticationException lastException = null;AuthenticationException parentException = null;Authentication result = null;Authentication parentResult = null;int currentPosition = 0;int size = this.providers.size();// 遍历所有的验证提供者for (AuthenticationProvider provider : getProviders()) {// 判断当前验证提供者是否支持传入的Authentication对象的类型if (!provider.supports(toTest)) {continue;}// 打印正在使用的验证提供者和当前位置logger.trace(LogMessage.format("Authenticating request with %s (%d/%d)",provider.getClass().getSimpleName(), ++currentPosition, size));try {// 调用当前验证提供者的authenticate方法进行身份验证result = provider.authenticate(authentication);// 如果验证成功,复制验证结果的详细信息到原始的Authentication对象中if (result != null) {//copyDetails(authentication, result);break;}} catch (AccountStatusException | InternalAuthenticationServiceException ex) {// 准备抛出异常并中止验证过程prepareException(ex, authentication);throw ex;} catch (AuthenticationException ex) {lastException = ex;}}// 如果当前验证提供者未能验证成功,并且存在父验证管理器,则尝试使用父验证管理器进行验证if (result == null && this.parent != null) {try {parentResult = this.parent.authenticate(authentication);result = parentResult;} catch (ProviderNotFoundException ex) {// 忽略该异常} catch (AuthenticationException ex) {parentException = ex;lastException = ex;}}// 如果验证成功,执行一些后续操作,如擦除验证结果中的敏感信息,并发布身份验证成功的事件if (result != null) {//((CredentialsContainer) result).eraseCredentials();//if (parentResult == null) {//    this.eventPublisher.publishAuthenticationSuccess(result);//}return result;}// 如果最后一个异常为空,则创建一个ProviderNotFoundException异常if (lastException == null) {lastException = new ProviderNotFoundException(this.messages.getMessage("ProviderManager.providerNotFound",new Object[] { toTest.getName() }, "No AuthenticationProvider found for {0}"));}// 如果父验证管理器的验证异常为空,则准备抛出最后一个异常if (parentException == null) {prepareException(lastException, authentication);}// 抛出最后一个异常throw lastException;
}
3 进入result = provider.authenticate(authentication);

其所属类public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider,
执行

// 确保传入的Authentication对象是UsernamePasswordAuthenticationToken的实例
Assert.isInstanceOf(UsernamePasswordAuthenticationToken.class, authentication,() -> this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.onlySupports","Only UsernamePasswordAuthenticationToken is supported"));// 获取用户名
String username = determineUsername(authentication);boolean cacheWasUsed = true;
// 从缓存中获取用户详细信息
UserDetails user = this.userCache.getUserFromCache(username);if (user == null) {cacheWasUsed = false;try {// 从数据源中检索用户详细信息user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);} catch (UsernameNotFoundException ex) {this.logger.debug("Failed to find user '" + username + "'");if (!this.hideUserNotFoundExceptions) {throw ex;}// 如果用户名未找到,抛出BadCredentialsException异常throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}// 确保retrieveUser方法的实现没有返回nullAssert.notNull(user, "retrieveUser returned null - a violation of the interface contract");
}try {// 对用户进行预身份验证检查this.preAuthenticationChecks.check(user);// 对用户进行额外的身份验证检查additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
} catch (AuthenticationException ex) {if (!cacheWasUsed) {throw ex;}// 如果出现问题,尝试再次进行身份验证检查,确保使用最新的数据(即不使用缓存)cacheWasUsed = false;user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);this.preAuthenticationChecks.check(user);additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication);
}// 对用户进行后身份验证检查
this.postAuthenticationChecks.check(user);if (!cacheWasUsed) {// 将用户详细信息放入缓存中this.userCache.putUserInCache(user);
}Object principalToReturn = user;
if (this.forcePrincipalAsString) {// 如果设置了forcePrincipalAsString为true,则返回用户名作为principalprincipalToReturn = user.getUsername();
}// 创建身份验证成功的Authentication对象
return createSuccessAuthentication(principalToReturn, authentication, user);
4 进入 user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication);

其所属类class DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider
执行

/*** 从用户详细信息服务中检索用户详细信息。** @param username      用户名* @param authentication 用于身份验证的`UsernamePasswordAuthenticationToken`对象* @return 用户详细信息* @throws AuthenticationException 如果发生身份验证异常*/
protected final UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication)throws AuthenticationException {// 准备防止时序攻击的措施prepareTimingAttackProtection();try {// 通过用户详细信息服务加载指定用户名的用户详细信息UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);if (loadedUser == null) {// 如果加载的用户详细信息为null,抛出InternalAuthenticationServiceException异常,违反了接口约定throw new InternalAuthenticationServiceException("UserDetailsService returned null, which is an interface contract violation");}return loadedUser;} catch (UsernameNotFoundException ex) {// 防止时序攻击mitigateAgainstTimingAttack(authentication);throw ex;} catch (InternalAuthenticationServiceException ex) {throw ex;} catch (Exception ex) {// 抛出InternalAuthenticationServiceException异常,将原始异常信息作为其原因throw new InternalAuthenticationServiceException(ex.getMessage(), ex);}
}
5 进入 UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username);

调用自己写的loadUserByUsername();

@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Autowiredprivate SysUserMapper sysUserMapper;@Autowiredprivate PasswordEncoder passwordEncoder;@Override@Transactionalpublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {UserDetailsInfo userDetailsInfo = sysUserMapper.getUserInfoByUsername(username);if(userDetailsInfo == null){throw  new UsernameNotFoundException("用戶不存在");}userDetailsInfo.setPassword(passwordEncoder.encode(userDetailsInfo.getPassword()));return userDetailsInfo;}
注:

用户名校验在这里插入图片描述
密码校验
在这里插入图片描述

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

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

相关文章

算法基础之约数之和

约数之和 核心思想&#xff1a; #include<iostream>#include<algorithm>#include<vector>#include<unordered_map>using namespace std;typedef long long LL;const int N 110 , mod 1e97;int main(){int n;cin>>n;unordered_map<int,int&…

需求:通过按钮的点击事件控制另一个输出框/按钮的点击

目录 第一章 接到需求 第二章 了解需求 第三章 解决需求 第四章 优化代码 第五章 解决问题 第一章 接到需求 最近开发的时候遇到这么一个事&#xff0c;技术经理是个全栈&#xff0c;已经把接口生成了&#xff0c;而且前端页面也写好了一个初稿&#xff0c;操作什么的功…

【已解决】taos时序数据库3.0版本,怎么按照时间分组?

taos数据库中按照时间分组&#xff0c;在2.4版本时候可以直接使用INTERVAL(time_unit)来查询。例如 前面可以直接添加_ts的。但是在3.0版本之后&#xff0c;如果直接使用的话&#xff0c;只会返回count&#xff1a; 没有前面的时间。那么在3.0版本时候&#xff0c;怎么修改呢&a…

在mt4上怎么查看CHFJPY品种的合约细则?

在MetaTrader 4 (MT4) 上查看CHFJPY品种的合约细则的方法如下&#xff1a; FXCM福汇官方个人注册登录流程 1.打开MT4软件并登录到您的交易账户。 2.在MT4界面的"市场观察"窗格中&#xff0c;找到并右键单击"CHFJPY"货币对。如果您无法找到"市场观察…

时间是如何定义的

每年365天&#xff0c;每天24小时&#xff0c;每小时60分钟&#xff0c;每分钟60s&#xff0c;这是我们习以为常的时间计量单位&#xff0c;那么在继续往下&#xff0c;1s是多少&#xff1f;几时几刻、几点几分是如何确定的&#xff1f;带着这些问题&#xff0c;展开本文。 1、…

常见分布的分布列/概率密度、分布函数、期望、方差、特征函数

0-1分布 二项分布 泊松分布 几何分布 均匀分布 正态分布 指数分布 伽马分布 卡方分布

2023.12.18 关于 CentOS7 安装 Redis5

目录 安装步骤 创建符号连接 修改配置文件 启动 redis 服务器 停止 redis 服务器 安装步骤 CentOS7 的 yum 仓库中&#xff0c;redis 的默认版本为 3 系列为了 能让 CentOS7 安装上 Redis5&#xff0c;此处我们需要安装额外软件源 1、安装额外软件源 yum install cento…

腾讯云消息队列11月产品月报 | RocketMQ 5.x 国际站上线

2023年 11月动态 消息队列 RocketMQ 版 1、5.x 形态国际站上线 国际站上线 5.x 集群全系列&#xff0c;第一批先开放新加坡和硅谷地域。 控制台链接&#xff1a;https://console.tencentcloud.com/trocketmq 2、 无感迁移能力 支持用户白屏化操作&#xff0c;将自建的 Roc…

提前预判和确认再做 现货白银投资的两种思路

在现货白银投资中&#xff0c;对于交易的步骤长期有两种看法。一种是提前预判行情并提前布局。另外一种是等待行情启动再做布局。这种两种方法要怎么选呢&#xff1f;笔者将从自己的角度出发&#xff0c;对这个问题进行讨论。 我们来看一下前一种的投资者&#xff0c;他们喜欢提…

标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;继续小雅兰西嘎嘎的学习&#xff0c;标准库中的string类&#xff0c;下面&#xff0c;让我们一起进入西嘎嘎string的世界吧&#xff01;&#xff01;&#xff01; string类的常用接口说明 Leetcode每日一题 string类的常用接口…

pip 常用指令 pip install 命令用法介绍

pip install 是一个 Python 包管理器命令&#xff0c;用于安装 Python 包。pip 是 Python 的一个重要工具&#xff0c;可以用来安装、升级和卸载 Python 包。 pip install 命令的一些常见参数有 -r&#xff1a;从一个需求文件中安装所有的包。-U 或 --upgrade&#xff1a;升级…

鸿蒙开发基本概念

1、开发准备 1.1、UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架可为开发者提供应用UI开发所必需的能力&#xff0c;比如多种组件、布局计算、动画能力、UI交互、绘制等。 方舟开发框架针对不同目的和技术…

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类&#xff0c;使用到了sklearn和tensorflow&#xff0c;并对图片分类进行了数据可视化展示 数据集介绍 UCI wine数据集&#xff1a; http://archive.ics.uci.edu/dataset/109/wine 这些数据是对意大利同一地区种植的葡萄酒进…

[SWPUCTF 2021 新生赛]jicao

首先打开环境 代码审计&#xff0c;他这儿需要进行GET传参和POST传参&#xff0c;需要进行POST请求 变量idwllmNB&#xff0c;进行GET请求变量json里需要含参数x以及jsonwllm 构造 得到flag

在线更换Proxmox VE超融合集群Ceph OSD磁盘

因为资源紧张的原因&#xff0c;担心一旦关机&#xff0c;虚拟机因为没有空闲的资源而被冻结&#xff0c;以致于不能漂移&#xff0c;导致部分服务停止&#xff0c;只好让机房帮忙热插拔。 幸运的是&#xff0c;插上去能够被系统所识别&#xff08;/dev/sdf就是新插入的硬盘&am…

华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)

第181题 如图所示,R1、R2、R3、R4都部署为SPF区域0,链路的cost值如图中标识。R1、R2R3、R4的Loopback0通告入OSPF。R1、R2、R3与R4使用Loopback0作为连接接口,建立BGP对等体关系,其中R4为RR设备,R1、R2、R3是R4的客户端。当R4的直连地址172.20,1,4/32通告入BGP后,以下关R…

mysql部署 --(docker)

先查找MySQL 镜像 Docker search mysql &#xff1b; 拉取mysql镜像&#xff0c;默认拉取最新的&#xff1b; 创建mysql容器&#xff0c;-p 代表端口映射&#xff0c;格式为 宿主机端口&#xff1a;容器运行端口 -e 代表添加环境变量&#xff0c;MYSQL_ROOT_PASSWORD是root用户…

2024云渲染平台推荐!免费云渲染平台(注册账号)推荐

近期&#xff0c;由于信息科技和云计算的迅猛发展&#xff0c;云渲染服务也逐步蓬勃发展并已达到成熟阶段&#xff0c;它因其高效办公、成本效益优越以及操作简便易行&#xff0c;赢得了广大设计师和 CG 艺术家的热烈欢迎&#xff0c;在过去的岁月里&#xff0c;创造一张高清晰…

OpenCV技术应用(8)— 如何将视频分解

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本节课就手把手教大家如何将一幅图像转化成热力图&#xff0c;希望大家学习之后能够有所收获~&#xff01;&#x1f308; 目录 &#x1f680;1.技术介绍 &#x1f680;2.实现代码 &#x1f680;1.技术介绍 视频是…

charles和谷歌浏览器在Mac上进行软件安装,桌面上会显示一个虚拟磁盘,关掉页面推出磁盘内容都消失掉了 需要再次安装问题解决

其他软件也会有这种情况&#xff0c;这里我们以charles为例。绿色背景的内容是重点步骤。 1.如图&#xff0c;我下载了一个charles一个版本的dmg文件。 2.打开后&#xff0c;选择Agree 3.桌面会出现一个磁盘和如下页面 4.错误操作------可以不看 直接看第5步正确操作 常规情…