SpringSecurity源码分析3--UserDetail部分

前言:本章提及的类都是与用户名、密码相关的类

UserDetailsService.class
用于加载用户信息
在这里插入图片描述

DaoAuthenticationProvider.class
将数据库的信息拿出来进行认证

在这里插入图片描述

AbstractUserDetailsAuthenticationProvider.class
DaoAuthenticationProvider的父类,通过模板模式,真正进行认证的模块,

一个允许子类重写和处理UserDetails对象的基AuthenticationProvider。该类旨在响应UsernamePasswordAuthenticationToken身份验证请求。
在这里插入图片描述

AuthenticationProvider.class

在这里插入图片描述

@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		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;
				}
				throw new BadCredentialsException(this.messages
						.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));
			}
			Assert.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;
			}
			// 可能存在用户数据变更的问题,需要再次尝试获取
			// There was a problem, so try again after checking
			// we're using latest data (i.e. not from the cache)
			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) {
			principalToReturn = user.getUsername();
		}
		return createSuccessAuthentication(principalToReturn, authentication, user);
	}

获取用户名
在这里插入图片描述

从缓存中获取UserDetail对象

在这里插入图片描述

private UserCache userCache = new NullUserCache();

在这里插入图片描述
默认都是null,可以通过setUserCache设置Cache

this.preAuthenticationChecks.check(user);

在这里插入图片描述

additionalAuthenticationChecks

在这里插入图片描述

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

public interface PasswordEncoder {
    String encode(CharSequence rawPassword);

    boolean matches(CharSequence rawPassword, String encodedPassword);

    default boolean upgradeEncoding(String encodedPassword) {
        return false;
    }
}

this.postAuthenticationChecks.check(user);

在这里插入图片描述

createSuccessAuthentication

在这里插入图片描述
权限管理

	private GrantedAuthoritiesMapper authoritiesMapper = new NullAuthoritiesMapper();

在这里插入图片描述retrieveUser

  1. 建议直接抛出UsernameNotFoundException
  2. 时间攻击防护

在这里插入图片描述
通过预先编码这个密码,可以确保在后续的时间攻击防护方法中,不会因为实时编码操作而导致时间差异,这些时间差异可能会被攻击者用来推断密码或其他敏感信息。
在这里插入图片描述
在这里插入图片描述
加密方法升级后,重新更新密码
在这里插入图片描述
在这里插入图片描述

UsernamePasswordAuthenticationFilter.class
根据请求中的username

在这里插入图片描述
在这里插入图片描述

AbstractAuthenticationProcessingFilter.class

在这里插入图片描述

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		if (!requiresAuthentication(request, response)) {
			chain.doFilter(request, response);
			return;
		}
		try {
			Authentication authenticationResult = attemptAuthentication(request, response);
			if (authenticationResult == null) {
				// return immediately as subclass has indicated that it hasn't completed
				return;
			}
			// 给session策略提供钩子
			this.sessionStrategy.onAuthentication(authenticationResult, request, response);
			// Authentication success
			if (this.continueChainBeforeSuccessfulAuthentication) {
				chain.doFilter(request, response);
			}
			successfulAuthentication(request, response, chain, authenticationResult);
		}
		catch (InternalAuthenticationServiceException failed) {
			this.logger.error("An internal error occurred while trying to authenticate the user.", failed);
			unsuccessfulAuthentication(request, response, failed);
		}
		catch (AuthenticationException ex) {
			// Authentication failed
			unsuccessfulAuthentication(request, response, ex);
		}
	}

在这里插入图片描述
在这里插入图片描述

FormLoginConfigurer.class

在这里插入图片描述
在这里插入图片描述
默认页面,生产不会使用
在这里插入图片描述
默认密码来源
在这里插入图片描述
默认加载的类
在这里插入图片描述

SecurityConfigurerAdapter.class

链式调用
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AbstractAuthenticationFilterConfigurer.class

在这里插入图片描述

@Override
	public void configure(B http) throws Exception {
		PortMapper portMapper = http.getSharedObject(PortMapper.class);
		if (portMapper != null) {
			this.authenticationEntryPoint.setPortMapper(portMapper);
		}
		// 设置请求缓存器
		RequestCache requestCache = http.getSharedObject(RequestCache.class);
		if (requestCache != null) {
			this.defaultSuccessHandler.setRequestCache(requestCache);
		}
		// 设置处理器
		this.authFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
		this.authFilter.setAuthenticationSuccessHandler(this.successHandler);
		this.authFilter.setAuthenticationFailureHandler(this.failureHandler);
		if (this.authenticationDetailsSource != null) {
			this.authFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource);
		}
		// 设置Session策略
		SessionAuthenticationStrategy sessionAuthenticationStrategy = http
				.getSharedObject(SessionAuthenticationStrategy.class);
		if (sessionAuthenticationStrategy != null) {
			this.authFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy);
		}
		// 记住我
		RememberMeServices rememberMeServices = http.getSharedObject(RememberMeServices.class);
		if (rememberMeServices != null) {
			this.authFilter.setRememberMeServices(rememberMeServices);
		}
		// 安全上下文
		SecurityContextConfigurer securityContextConfigurer = http.getConfigurer(SecurityContextConfigurer.class);
		if (securityContextConfigurer != null && securityContextConfigurer.isRequireExplicitSave()) {
			// 安全上下文仓库
			SecurityContextRepository securityContextRepository = securityContextConfigurer
					.getSecurityContextRepository();
			this.authFilter.setSecurityContextRepository(securityContextRepository);
		}
		// 添加过滤器
		F filter = postProcess(this.authFilter);
		http.addFilter(filter);
	}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Web的宠物医院信息管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本宠物医院信息管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据…

【海思Hi3516CV610】是面向新一代视频编解码标准、网络安全和隐私保护、人工智能行业应用方面的IPC SoC

海思Hi3516CV610是面向新一代视频编解码标准、网络安全和隐私保护、人工智能行业应用方面的IPC SoC,除了开发普通摄像机,还可以打造极具竞争力的枪球一体机、双目长短焦摄像机产品; 处理器内核: 支持ARM Cortex-A7 MP2 时钟速率950MHz 支持…

java中的枚举概述

枚举指的是将一个事物的所有情况列举出来,这个概念在数学中的概率那一块经常有所体现。用一个简单的例子加以说明,我们对投掷两个骰子时出现的点数进行记录,当把所有可能出现的情况都列举出来时,所体现的就是枚举的概念。这里可能…

C++_类型转换

文章目录 学习目标:1.static_cast2. reinterpret_cast3.const_cast4. dynamic_cast 学习过程1.static_cast2. reinterpret_cast3.const_cast在这里插入图片描述4. dynamic_cast 学习目标: 标准C为了加强类型转换的可视性,引入了四种命名的强…

Web程序设计-实验03 JavaScript语言基础

题目 【实验主题】 素数问题求解。计算(判断) 1~100中哪些是素数、哪些是合数。 素数也称为质数,是只能被1及其自身整除的自然数。与素数相对应的是合数,合数可以被分解为若干个素数的乘积,这些素数称为这个合数的质…

IntelliJ-platform plugIn 插件开发专题内容介绍,学习指导(一)

这系列文章出炉对于笔者来说确实不容易,历时快两年了,先后迭代了3版本,暂时与官方最新版本API同步(2024.03),文章内容覆盖2022~2024版内容 专题由来 最早接触插件开发是源于公司一个国际化项目&#xff0c…

什么是网络安全,企业如何做好网络安全等级评测

网络安全从其本质上讲就是网络上的信息安全,指网络系统的硬件、软件及数据受到保护。不遭受破坏、更改、泄露,系统可靠正常地运行,网络服务不中断。从用户的角度,他们希望涉及到个人和商业的信息在网络上传输时受到机密性、完整性…

Meta Llama 3 简介

文章目录 要点我们对 Llama 3 的目标最先进的性能模型架构训练数据扩大预训练规模指令微调与 Llama 3 一起建造系统级责任方法大规模部署 Llama 3Llama 3 的下一步是什么?立即尝试 Meta Llama 3 本文翻译自:https://ai.meta.com/blog/meta-llama-3/ 要点…

【个人博客搭建】(5)Sqlsugar实体创建数据库数据

1、在appsettings.json文件中配置SqlServer数据库连接字符串信息。(后续考虑添加MySQL数据库等类型) "DBS": [/*对应下边的 DBTypeMySql 0,SqlServer 1,*/{"ConnId": "plateau.poetize.2024","DBType": 1,&qu…

便携式HD-SDI模拟源测试设备

便携式HD-SDI模拟源测试设备 平台简介 便携式手提CameraLink模拟源测试设备,以PCIe的HD-SDI播出卡和X86主板为基础,构建便携式的手提设备。 平台默认操作系统为win7 64位系统;具备丰富的外设接口,如VGA、HDMI、千兆网口、USB2.0/3…

ADOP 万兆电口光模块:SFP+转RJ45端口解决方案

🌵在数据中心的接入层中,大多数服务器网卡(NIC)和存储设备都采用10GBASE-T RJ45端口,而与之相连的TOR(机架顶部)交换机通常配备SFP端口,且二者无法直接相连。为了解决该问题&#xf…

[大模型]Qwen-7B-hat Transformers 部署调用

Qwen-7B-hat Transformers 部署调用 环境准备 在autodl平台中租一个3090等24G显存的显卡机器,如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab,并且打开其中的终端开始环境配置、模型下…

AI大模型探索之路-应用篇17:GLM大模型-大数据自助查询平台架构实践

文章目录 前言一、技术架构设计二、本地知识库准备三、SQLServer服务1. 数据库准备步骤1:安装MySQL数据库步骤2:启动MySQL数据库步骤3:登录MySQL数据库步骤4:创建数据库用户glm步骤5:给数据库用户赋权限步骤6&#xff…

分布式锁(Redis)

一、序言 本文和大家聊聊分布式锁以及常见的解决方案。 二、什么是分布式锁 假设一个场景:一个库存服务部署在上面三台机器上,数据库里有 100 件库存,现有 300 个客户同时下单。并且这 300 个客户均摊到上面的三台机器上(即三台…

AI绘画 究竟在哪些方面降低了门槛

AI绘画的产物是图像。图像对人类的认知、情感和文化发展起着重要的作用,包括信息传递、创造性表达、历史记录、审美享受和交流。 从原来的纸笔调色板到数字时代的数字板、绘图软件,再到AI绘画时代,任何人都可以用几行简单的文字创作出高质量…

在PostgreSQL中如何创建和使用自定义函数,包括内置语言(如PL/pgSQL)和外部语言(如Python、C等)?

文章目录 一、使用内置语言 PL/pgSQL 创建自定义函数示例代码使用方法 二、使用外部语言 Python 创建自定义函数安装 PL/Python 扩展示例代码使用方法 三、使用外部语言 C 创建自定义函数编写 C 代码编译为共享库在 PostgreSQL 中注册函数注意事项 总结 PostgreSQL 是一个强大的…

【Java开发指南 | 第十七篇】Java 方法

读者可订阅专栏:Java开发指南 |【CSDN秋说】 文章目录 简介语法实例构造方法 简介 Java中的方法是用来执行特定任务的一组语句,可以重复使用。它们包含在类或对象中,并通过调用来执行。 举个例子,println() 是一个方法&#xff…

论文阅读:BEVBert: Multimodal Map Pre-training for Language-guided Navigation

BEVBert:语言引导导航的多模态地图预训练 摘要 现存的问题:目前大多数现有的预训练方法都采用离散的全景图来学习视觉-文本关联。这要求模型隐式关联全景图中不完整、重复的观察结果,这可能会损害智能体的空间理解。 本文解决方案&#xf…

Android开发:应用百度智能云中的身份证识别OCR实现获取个人信息的功能

百度智能云: 百度智能云是百度提供的公有云平台,于2015年正式开放运营。该平台秉承“用科技力量推动社会创新”的愿景,致力于将百度在云计算、大数据、人工智能的技术能力向社会输出。 百度智能云为金融、城市、医疗、客服与营销、能源、制造…

【漏洞复现】泛微e-cology ProcessOverRequestByXml接口存在任意文件读取漏洞

漏洞描述 泛微e-cology依托全新的设计理念,全新的管理思想。 为中大型组织创建全新的高效协同办公环境。 智能语音办公,简化软件操作界面。 身份认证、电子签名、电子签章、数据存证让合同全程数字化。泛微e-cology ProcessOverRequestByXml接口存在任意文件读取漏洞 免责声…
最新文章