Spring Security基本源码解析(超精细版)

一、基本源码解析

1.1 UsernamePasswordAuthenticationFilter

用户名称和密码的过滤器

浏览器发送用户名称和密码 ----》 经过过滤器「UsernamePasswordAuthenticationFitler」

1.2 UsernamePasswordAuthenticationFilter核心方法

重写父类「AbstractAuthenticationProcessingFilter.java」当中的抽象方法.

@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)throws AuthenticationException {if (this.postOnly && !request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String username = obtainUsername(request);username = (username != null) ? username.trim() : "";String password = obtainPassword(request);password = (password != null) ? password : "";UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username,password);// Allow subclasses to set the "details" propertysetDetails(request, authRequest);// 调用认证方法.return this.getAuthenticationManager().authenticate(authRequest);
}

1.3 AuthenticationManager「重点」

认证管理器.

this.getAuthenticationManager(), 这里获取的是实现类的对象.

protected AuthenticationManager getAuthenticationManager() {return this.authenticationManager;
}
​
public void setAuthenticationManager(AuthenticationManager authenticationManager) {this.authenticationManager = authenticationManager;
}

AuthenticationManager接口源码

public interface AuthenticationManager {// 核心认证方法.// 参数: Authentication, 认证接口// 返回值: Authentication, 认证接口Authentication authenticate(Authentication authentication) throws AuthenticationException; 
}

实现类

1.4 Authentication接口

认证接口.

// 认证接口.
public interface Authentication extends Principal, Serializable {// 获取所有的权限Collection<? extends GrantedAuthority> getAuthorities();// 用户凭证, 通常这里指的密码.Object getCredentials();// 存储有关身份验证请求的其他详细信息。这些可能是 IP 地址、证书序列号等。Object getDetails();// 要进行身份验证的主体的身份。对于带有用户名和密码的身份验证请求,这将是用户名。调用方应填充身份验证请求的主体。// AuthenticationManager 实现通常会返回包含更丰富信息的身份验证作为应用程序使用的主体。许多身份验证提供程序将创建一个UserDetails对象作为主体。// 返回:// Principal被身份验证或身份验证后的身份验证主体。Object getPrincipal();// 是否已经认证过boolean isAuthenticated();// 有关完整说明,请参阅 isAuthenticated() 。// 实现应 始终 允许使用参数调用 false 此方法,因为各种类使用它来指定不应信任的身份验证令牌。如果实现希望拒绝带有参数的 true 调用(这将指示身份验证令牌受信任 - 潜在的安全风险),则实现应抛出 IllegalArgumentException.void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}

1.5 ProviderManager

// AuthenticationManager接口的实现类. 一般情况下都会这东西.
public class ProviderManager implements AuthenticationManager, MessageSourceAware, InitializingBean {// 存放各种各样的providers的集合.private List<AuthenticationProvider> providers = Collections.emptyList();// 核心认证方法.@Overridepublic 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()) {if (!provider.supports(toTest)) {continue;}if (logger.isTraceEnabled()) {logger.trace(LogMessage.format("Authenticating request with %s (%d/%d)",provider.getClass().getSimpleName(), ++currentPosition, size));}try {// 执行各种各样的认证.result = provider.authenticate(authentication);if (result != null) {copyDetails(authentication, result);break;}}catch (AccountStatusException | InternalAuthenticationServiceException ex) {prepareException(ex, authentication);// SEC-546: Avoid polling additional providers if auth failure is due to// invalid account statusthrow ex;}catch (AuthenticationException ex) {lastException = ex;}}if (result == null && this.parent != null) {// Allow the parent to try.try {parentResult = this.parent.authenticate(authentication);result = parentResult;}catch (ProviderNotFoundException ex) {// ignore as we will throw below if no other exception occurred prior to// calling parent and the parent// may throw ProviderNotFound even though a provider in the child already// handled the request}catch (AuthenticationException ex) {parentException = ex;lastException = ex;}}if (result != null) {if (this.eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) {// Authentication is complete. Remove credentials and other secret data// from authentication((CredentialsContainer) result).eraseCredentials();}// If the parent AuthenticationManager was attempted and successful then it// will publish an AuthenticationSuccessEvent// This check prevents a duplicate AuthenticationSuccessEvent if the parent// AuthenticationManager already published itif (parentResult == null) {this.eventPublisher.publishAuthenticationSuccess(result);}
​return result;}
​// Parent was null, or didn't authenticate (or throw an exception).if (lastException == null) {lastException = new ProviderNotFoundException(this.messages.getMessage("ProviderManager.providerNotFound",new Object[] { toTest.getName() }, "No AuthenticationProvider found for {0}"));}// If the parent AuthenticationManager was attempted and failed then it will// publish an AbstractAuthenticationFailureEvent// This check prevents a duplicate AbstractAuthenticationFailureEvent if the// parent AuthenticationManager already published itif (parentException == null) {prepareException(lastException, authentication);}throw lastException;}
}

1.6 AuthenticationProvider

提供各种认证器.它是一个接口.

public interface AuthenticationProvider {// 使用与 相同的 AuthenticationManager.authenticate(Authentication) 协定执行身份验证。// 参数:// authentication – 身份验证请求对象。// 返回:// 包含凭据的完全身份验证的对象。如果 无法支持对传递Authentication的对象进行身份验证,则AuthenticationProvider可能返回null。在这种情况下,将尝试下一个AuthenticationProvider支持所呈现Authentication类的方法。// 抛出:// AuthenticationException – 如果身份验证失败。Authentication authenticate(Authentication authentication) throws AuthenticationException;// 如果支持AuthenticationProvider指示Authentication的对象,则返回true。// 返回并不true保证 将AuthenticationProvider能够对所呈现的类实例Authentication进行身份验证。它只是表明它可以支持对它的更仔细的评估。仍然可以从该方法返回 null authenticate(Authentication) can AuthenticationProvider 以指示应尝试另一个AuthenticationProvider方法。// 选择能够执行身份验证的在AuthenticationProvider运行时进行。ProviderManager// 参数:// authentication// 返回:// true 如果实现可以更仔细地评估所呈现的 Authentication 类boolean supports(Class<?> authentication);
}

这里般用的是: DaoAuthenticationProvider.

1.7 UserDetailsService 「重要」

  • 加载用户特定数据的核心界面。它在整个框架中用作用户 DAO,并且是 .DaoAuthenticationProvider该接口只需要一种只读方法,这简化了对新数据访问策略的支持。另请参阅:org.springframework.security.authentication.dao.DaoAuthenticationProvider, UserDetails

public interface UserDetailsService {// 根据用户名定位用户。在实际实现中,搜索可能区分大小写或不区分大小写,具体取决于实现实例的配置方式。在这种情况下, UserDetails 返回的对象可能具有与实际请求的用户名不同的大小写。// 参数:// username – 标识需要其数据的用户的用户名。// 返回:// 完全填充的用户记录(从不 null)// 抛出:// UsernameNotFoundException – 如果找不到用户或用户没有授权UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}

1.8 UserDetails 「重要」

实现类是User对象,这个User由spring security提供的.

提供核心用户信息。出于安全目的,Spring 安全性不会直接使用实现。它们只是存储用户信息,这些信息随后封装到对象中 Authentication 。这允许将非安全相关的用户信息(例如电子邮件地址、电话号码等)存储在方便的位置。具体的实现必须特别注意确保强制执行针对每种方法详述的非空协定。有关参考实现(您可能希望在代码中扩展或使用),请参阅 User 。

public interface UserDetails extends Serializable {
​/*** Returns the authorities granted to the user. Cannot return <code>null</code>.* @return the authorities, sorted by natural key (never <code>null</code>)*/Collection<? extends GrantedAuthority> getAuthorities();
​String getPassword();String getUsername();boolean isAccountNonExpired();boolean isAccountNonLocked();boolean isCredentialsNonExpired();boolean isEnabled();
}

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

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

相关文章

spring6中如何不使用@RequestParam注解

RequestParam的使用场景 RequestParam注解可以用在GET和POST请求中&#xff0c;用于指定请求路径或请求体的参数&#xff0c;通常请求格式为表单格式 什么情况下可以不使用RequestParam注解 当Controller方法的参数名与请求中的参数名一致时&#xff0c;可以不用RequestPar…

2.4章节python中字符串类型

在Python中&#xff0c;字符串&#xff08;String&#xff09;是一种基本的数据类型&#xff0c;用于表示文本信息。字符串可以包含字母、数字、标点符号或任何Unicode字符。Python中的字符串是不可变的&#xff0c;这意味着一旦创建了字符串&#xff0c;就不能更改字符串中的字…

Build a Large Language Model (From Scratch)附录D(gpt-4o翻译版)

来源&#xff1a;https://github.com/rasbt/LLMs-from-scratch?tabreadme-ov-file https://www.manning.com/books/build-a-large-language-model-from-scratch

C++实现简化 QtBase(4):增加简单实用的事件机制

前面的文章已经实现了许多QObject的功能了&#xff1a; C实现一个简单的Qt信号槽机制 C实现简化版Qt信号槽机制&#xff08;2&#xff09;&#xff1a;增加内存安全保障 C实现简化版Qt的QObject&#xff08;3&#xff09;&#xff1a;增加父子关系、属性系统 但是&#xff0c;…

Windows 下载安装ffmpeg

下载地址 https://ffmpeg.org/download.html 测试 管理员方式打开控制台&#xff0c;输入ffmpeg测试 配置环境变量

让你的 Rabbids Rockstar人物化身加入欢乐行列!

让你的 Rabbids Rockstar 人物化身加入欢乐行列&#xff01; https://www.youtube.com/watch?vwLBd20BxbS8 当这些调皮的小兔子以狂野的装扮、超棒的吉他弹奏和搞笑滑稽的动作登上舞台中央时&#xff0c;你将感受到它们异想天开的魅力。通过人物化身释放你内心的摇滚明星魅力&…

Eigen 欧拉角转旋转矩阵相互转换

目录 一、什么是欧拉角 二、理解欧拉角 2.1 旋转顺序 2.2 内旋和外旋 2.3 万向锁 2.4 如何避面出现万向锁 三、欧拉角与旋转矩阵相互转化 3.1 欧拉角转旋转矩阵 3.2 代码示例 3.3 旋转矩阵转欧拉角 3.4 代码示例 一、什么是欧拉角 欧拉角(Euler Angles)就是物体绕…

【收藏级神丹】Liae384_刘亦菲_直播可用,平衡度最高的原创神丹,独家珍稀资源

Liae384_刘亦菲_DFL神丹&#xff1a;点击下载 此丹较重&#xff0c;小卡可以使用但不能训练&#xff0c;实测复训适合24G卡8G、12G、16G卡下载练好的专丹直接使用即可384的Liae对各类杂论视频兼容比较好&#xff0c;高参也能容忍高分辨率的DST复用方式: 非必要不用删除AB&…

Go源码--channel源码解读

简介 channel顾名思义就是channel的意思&#xff0c;主要用来在协程之间传递数据&#xff0c;所以是并发安全的。其实现原理&#xff0c;其实就是一个共享内存再加上锁&#xff0c;底层阻塞机制使用的是GMP模型。可见 GMP模型就是那个道&#xff0c;道生一,一生二,二生三,三生…

【Mathematica14.0】快速从下载安装到使用

目录 1.简介 2.下载安装 下载 安装 3.一小时掌握mathematica使用 单元模式 内置函数 符号表达式 迭代器 赋值 通配符及查找替换 函数定义 匿名函数&#xff08;拉姆达表达式&#xff09; 函数映射 函数式与运算符 函数自定义选项 图形可视化 交互式界面 数值…

Rocky Linux 9.4基于官方源码制作openssh 9.8p1二进制rpm包 —— 筑梦之路

2024年7月1日&#xff0c;openssh 9.8版本发布&#xff0c;主要修复了CVE-2024-6387安全漏洞。 由于centos 7的生命周期在6月30日终止&#xff0c;因此需要逐步替换到Rocky Linux&#xff0c;后续会有更多分享关于Rocky Linux的文章。 环境说明 1. 操作系统版本 cat /etc/o…

【论文阅读】-- Strscope:不规则测量的时间序列数据的多尺度可视化

Stroscope: Multi-Scale Visualization of Irregularly Measured Time-Series Data 摘要1 引言2相关工作2.1&#xff08;大型&#xff09;时间序列数据可视化2.2 事件序列数据可视化2.3 评价 3问题分析3.1 数据集3.2 场景——现状3.3 设计流程3.4 设计原理 4 涟漪图&#xff1a…

极限学习机(Extreme Learning Machine,ELM)及其Python和MATLAB实现

极限学习机&#xff08;Extreme Learning Machine&#xff0c;ELM&#xff09;是一种快速而有效的机器学习算法&#xff0c;最初由马洪亮等人于2006年提出。ELM是一种单隐层前馈神经网络&#xff0c;其背景源于对传统神经网络训练过程中反向传播算法的改进与优化。相比传统神经…

JAVA连接PLC实现点位数据的读写操作-iot-communication

iot-communication 简介 iot-communication 是一个开源项目,主要服务于物联网(IoT)领域的开发者,提供了一套全面且深入的工具集,以促进物联网应用的开发。该项目是由 Oscura(网名 xingshuang)创建的,并且自2019年启动以来持续更新,到了2024年已经发布了 v1.5.0 版本。…

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…

针对某客户报表系统数据库跑批慢进行性能分析及优化

某客户报表系统数据库跑批时间过长&#xff0c;超出源主库较多&#xff0c;故对其进行了分析调优&#xff0c;目前状态如下&#xff1a; 1、业务连接的rac的scanip&#xff0c;因为负载均衡将跑批的连接连接到了多个计算节点导致节点间通讯成本较高&#xff0c;故速率缓慢&…

HexPlane: A Fast Representation for Dynamic Scenes一种动态场景的快速表示方法

Abstract 动态三维场景的建模与再现是三维视觉领域的一个具有挑战性的课题。先前的方法基于 NERF 并依赖于隐式表示这是缓慢的&#xff0c;因为它需要许多 MLP 评估&#xff0c;限制真实世界的应用程序。我们展示了动态三维场景可以明确地表示为六个平面的学习功能&#xff0c…

10.10记录

云轴-电话面试 python- 深拷贝和浅拷贝 copy.copy()&#xff1a;浅拷贝是创建一个新对象&#xff0c;但是新对象的元素是原对象的引用。也就是说&#xff0c;新对象和原对象共享同一块内存空间。当原对象的元素发生改变时&#xff0c;新对象的元素也会随之改变。 copy.deepco…

SQL语句(DCL)

DCL英文全称Data Control Language&#xff08;数据控制语言&#xff09;,用来管理数据库用户、控制数据库的访问权限 DCL-管理用户 create user itcastlocalhost identified by 123456 ;-- 修改用户heima的密码为1234 alter user heima% identified with mysql_native_passwo…

C++ windows下使用openvino部署yoloV8

目录 准备版本&#xff1a; 准备事项: 选择配置界面&#xff1a; 下载界面&#xff1a; ​编辑 添加VS配置&#xff1a; 准备代码&#xff1a; yolov8.h yolov8.cpp detect.cpp 如何找到并放置DLL&#xff1a; 准备版本&#xff1a; opencv 4.6.0 openvino 2024.0…