-
Spring-Security源码解读:
1.使用ctrl+shift+n组合键查找UsernamePasswordAuthenticationFilter过滤器,该过滤器是用来处理用户认证逻辑的,进入后如图:
-

-
(1)可以看到它默认的登录请求url是"/login",并且只允许POST方式的请求
(2)obtainUsername()方法点进去发现它默认是根据参数名为"username"和"password"来获取用户名和密码的
(3)通过构造方法实例化一个UsernamePasswordAuthenticationToken对象,此时调用的是UsernamePasswordAuthenticationToken的两个参数的构造函数,如图:
-

其中super(null)调用的是父类的构造方法,传入的是权限集合,因为目前还没有认证通过,所以不知道有什么权限信息,这里设置为null,然后将用户名和密码分别赋值给principal和credentials,同样因为此时还未进行身份认证,所以setAuthenticated(false)
(4)setDetails(request, authRequest)是将当前的请求信息设置到UsernamePasswordAuthenticationToken中
(5)通过调用getAuthenticationManager()来获取AuthenticationManager,通过调用它的authenticate方法来查找支持该token(UsernamePasswordAuthenticationToken)认证方式的provider,然后调用该provider的authenticate方法进行认证
2.AuthenticationManager是用来管理AuthenticationProvider的接口,通过查找后进入,然后使用ctrl+H组合键查看它的继承关系,找到ProviderManager实现类,它实现了AuthenticationManager接口,查看它的authenticate方法,它里面有段这样的代码:
-
for (AuthenticationProvider provider : getProviders()) { if (!provider.supports(toTest)) { continue; } ... try { result = provider.authenticate(authentication); ... } }通过for循环遍历AuthenticationProvider对象的集合,找到支持当前认证方式的AuthenticationProvider,找到之后调用该AuthenticationProvider的authenticate方法进行认证处理:
-
result = provider.authenticate(authentication);3.AuthenticationProvider接口,就是进行身份认证的接口,它里面有两个方法:authenticate认证方法和supports是否支持某种类型token的方法,通过ctrl+h查看继承关系,找到AbstractUserDetailsAuthenticationProvider抽象类,它实现了AuthenticationProvider接口,它的supports方法如下: public boolean supports(Class<?> authentication) { return (UsernamePasswordAuthenticationToken.class .isAssignableFrom(authentication)); } 说明它是支持UsernamePasswordAuthenticationToken类型的AuthenticationProvider 再看它的authenticate认证方法,其中有一段这样的代码: boolean cacheWasUsed = true; UserDetails user = this.userCache.getUserFromCache(username); if (user == null) { cacheWasUsed = false; try { user = retrieveUser(username, (UsernamePasswordAuthenticationToken) authentication); } ... } 如果从缓存中没有获取到UserDetails,那么它调用retrieveUser方法来获取用户信息UserDetails,这里的retrieveUser是抽象方法,等一会我们看它的子类实现。 用户信息UserDetails是个接口,我们进入查看,它包含以下6个接口方法: Collection<? extends GrantedAuthority> getAuthorities();//获取权限集合 String getPassword(); //获取密码 String getUsername(); //获取用户名 boolean isAccountNonExpired(); //账户未过期 boolean isAccountNonLocked(); //账户未锁定 boolean isCredentialsNonExpired(); //密码未过期 boolean isEnabled(); //账户可用 查看它的继承关系发现User类实现了该接口,并实现了该接口的所有方法 接着AbstractUserDetailsAuthenticationProvider往下看,找到下面的代码: preAuthenticationChecks.check(user); additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken) authentication); preAuthenticationChecks预检查,在最下面的内部类DefaultPreAuthenticationChecks中可以看到,它会检查上面提到的三个boolean方法,即检查账户未锁定、账户可用、账户未过期,如果上面的方法只要有一个返回false,就会抛出异常,那么认证就会失败。 additionalAuthenticationChecks是附加检查,是个抽象方法,等下看子类的具体实现。 下面还有个postAuthenticationChecks.check(user)后检查,在最下面的DefaultPostAuthenticationChecks内部类中可以看到,它会检查密码未过期,如果为false就会抛出异常 如果上面的检查都通过并且没有异常,表示认证通过,会调用下面的方法: createSuccessAuthentication(principalToReturn, authentication, user); 跟进发现此时通过构造方法实例化对象UsernamePasswordAuthenticationToken时,调用的是三个参数的构造方法: public UsernamePasswordAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) { super(authorities); this.principal = principal; this.credentials = credentials; super.setAuthenticated(true); // must use super, as we override } 此时会调用父类的构造方法设置权限信息,并调用父类的setAuthenticated(true)方法,到这里就表示认证通过了。 下面我们看看AbstractUserDetailsAuthenticationProvider的子类,同ctrl+h可查看继承关系,找到DaoAuthenticationProvider 4.DaoAuthenticationProvider类 (1)查看additionalAuthenticationChecks附加检查方法,它主要是检查用户密码的正确性,如果密码为空或者错误都会抛出异常 (2)获取用户信息UserDetails的retrieveUser方法,主要看下面这段代码: UserDetails loadedUser = this.getUserDetailsService().loadUserByUsername(username); 它是调用了getUserDetailsService先获取到UserDetailsService对象,通过调用UserDetailsService对象的loadUserByUsername方法获取用户信息UserDetails 找到UserDetailsService,发现它是一个接口,查看继承关系,有很多实现,都是spring-security提供的实现类,并不满足我们的需要,我们想自己制定获取用户信息的逻辑,所以我们可以实现这个接口。比如从我们的数据库中查找用户信息 5.SecurityContextPersistenceFilter过滤器 那么用户认证成功之后,又是怎么保存认证信息的呢,在下一次请求过来是如何判断该用户是否已经认证了呢? 请求进来时会经过SecurityContextPersistenceFilter过滤器,进入SecurityContextPersistenceFilter过滤器并找到以下代码: SecurityContext contextBeforeChainExecution = repo.loadContext(holder); 从session中获取SecurityContext对象,如果没有就实例化一个SecurityContext对象 SecurityContextHolder.setContext(contextBeforeChainExecution); 将SecurityContext对象设置到SecurityContextHolder中 chain.doFilter(holder.getRequest(), holder.getResponse()); 表示放行,执行下一个过滤器 执行完后面的过滤并经过servlet处理之后,响应给浏览器之前再次经过此过滤器。查看以下代码: SecurityContext contextAfterChainExecution = SecurityContextHolder.getContext(); SecurityContextHolder.clearContext(); this.repo.saveContext(contextAfterChainExecution, holder.getRequest(), holder.getResponse()); 通过SecurityContextHolder获取SecurityContext对象,然后清除SecurityContext,最后将获取的SecurityContext对象放入session中 其中SecurityContextHolder是与ThreadLocal绑定的,即本线程内所有的方法都可以获得SecurityContext对象,而SecurityContext对象中包含了Authentication对象,即用户的认证信息,spring-security判断用户是否认证主要是根据SecurityContext中的Authentication对象来判断。Authentication对象的详细信息如图:
最后整个过程的流程大致如下图:
-

相关推荐
【Origin+Python】使用External Python批量出图代码参考2
不使用part2 的代码,自己打开一个origin2022的界面。这里主要介绍一些进阶代码以及使用盗版origin要如何。3 批量绘制相同设置的曲线图。然后就是没有水印的图片了。
SpringSecurity过滤器链和认证过程y源码分析
介绍 SpringSecurity核心功能:认证(身份校验,你是谁),授权(你能干什么),攻击防护(防止伪造身份) 一、原理过滤器链 REST API:相当于应用的controller,用户的增删该查的一些服务 Spring Security过滤器链:这个是最核心的部分,相当于一组Filter,请求和响应都会经过过滤器,这些过滤器在系统启动的时候,Spring boot会自动把它们都配置进...
WGCNA加权基因共表达网络分析(1)简介、原理
WGCNA简介 WGCNA(Weighted Gene Co-Expression Network Analysis, 加权基因共表达网络分析),鉴定表达模式相似的基因集合(module),解析基因集合与样品表型之间的联系,绘制基因集合之间的调控网络并鉴定关键调控基因 WGCNA适用于复杂的转录组数据(样本数目较多) 研究不同器官/组织类型和不同阶段的发育调控、生物和非生物胁迫的不同时间响应机制 WGCNA原理 原理概要 1.构建基因共表达网络:先构建基因共表达网络,通常利用两两基因之间的表达模式来计算
spring security单点登录跳过密码验证
spring security单点登录跳过密码验证
MATPOWER下载安装教程
将MATPOWER文件复制在C:\Program Files (x86)\MATLAB\R2016b\bin目录下。原来的窗口中多了很多文件路径,点击【保存】,再点击【关闭】选择所要添加的MATPOWER文件夹,点击【选择文件夹】二、将MATPOWER放在bin目录下。找到菜单栏的【设置路径】点击【添加并包含子文件】一、从官网下载后解压。
实战指南:如何优雅解决SpringBoot3与Mybatis-Plus的版本兼容性问题
本文深入解析SpringBoot3与Mybatis-Plus的版本兼容性问题,提供实战解决方案。通过Maven依赖排除策略、Gradle配置方案及自动配置覆盖策略,有效解决包冲突和初始化顺序问题,确保项目平稳升级。适用于开发者快速解决SpringBoot3与Mybatis-Plus的集成难题。
Spring Security登录的简单解析
简单的解析登录
FreeRTOS OTA实战:从Bootloader设计到安全升级的完整流程(附MQTT示例代码)
本文详细介绍了在FreeRTOS系统中实现安全OTA固件升级的完整流程。内容涵盖从Bootloader设计、存储分区规划到与MQTT协议集成的OTA Agent任务开发,并重点解析了固件签名验证、防回滚等关键安全机制,为嵌入式物联网设备提供了一套高可靠性的远程升级解决方案。
SpringSecurity
一、导入依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> 二、在yml中设置自定义密码: spring: security: u
初探802.11协议(6)——Wi-Fi 6新特性简介
Wi-Fi 6新机制(特性)介绍
【云原生】Docker可视化工具Portainer使用详解
Docker可视化工具Portainer使用详解
arXiv Journal 2021-01-12
2021-01-12 hep-ph: 4 papers hep-exp: 1 paper hep-ph: 4 papers Title: Leading Logs in QCD Axion Effective Field Theory [arXiv:2101.03173] Abstract: The axion is much lighter than all other degrees of freedom introduced by the Peccei-Quinn
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
在探讨计算机性能优化的旅程中,我们常常被引导去关注算法的复杂度、代码的优化,或是更高效的数据结构。然而,有一个经常被忽视的角色在幕后默默地影响着程序的运行效率——那就是缓存(Cache)。正如哲学家亨利·戴维·梭罗在《瓦尔登湖》中所说:“细节是造成美丽的源泉”,在软件开发的世界里,对缓存的理解和优化,就是那些决定程序性能优雅与否的细节。
2021-12-01
TransCD: 一个基于Transformer的场景变化检测模型 TransCD: Scene Change Detection via Transformer-based Architecture摘要新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowc
C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片
基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正
NTscan扫描工具
ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。
1908



被折叠的 条评论
为什么被折叠?



