Spring Security(maven项目) 3.0.2.9版本 --- 改
前言:
通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷,而实践和认识之每一循环的内容,都比较地进到了高一级的程度。
本期目标:
针对上一期的java配置进行修改,优化可读性,易上手程度
正片:
Spring Security Java配置
基于Security Filter Chain,我们对配置进行了分类
第一类:Security Filter配置(客体)
第二类:Security Filter Chain配置(主体)
基本结构
第一类配置模板:
@Configuration //用于标记一个类为配置类,表示该类包含Bean的定义。
@EnableWebSecurity //其中一个功能:注入SecurityFilterChain
public class WebSecurityConfig {//自定义Security Filter 配置......}
第二类配置模板:
public class SecurityWebApplicationInitializerextends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {// 注册Security Filter Chain// 话口号内公式:带有@EnableWebSecurity的类// 一般情况,一个配置可以完成全部功能return new Class[]{WebSecurityConfig.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[0];}@Overrideprotected String[] getServletMappings() {return new String[0];}
}
注意:两段代码的类名不是同一个!侧面表示,不是同一个类

启动程序,运用对比
仅添加框架,无任何配置
基础配置,但未注册
无基础配置,但注册
基础配置并注册
统一内容,无须对比(官方提供的表单登录)

成功登录后

对比内容:
打印日志,登录用的账号密码
对比方式:对代码进行注释化,再启动
在正式对比前,先完善配置
package example.hello_security;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;@Configuration //用于标记一个类为配置类,表示该类包含Bean的定义。
@EnableWebSecurity //其中一个功能:注入SecurityFilterChain
public class WebSecurityConfig {//基本配置@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());return manager;}}
对比开始
第一轮对比:日志

无配置

有配置,无注册

无配置,有注册

有配置,有注册
通过对比,我们发现了日志中的差距,有配置的没有下面两句话
Using generated security password: e06ee57c-1f9b-4e23-ab3c-058b6a6f85fb
使用生成的安全密码:e06ee57c-1f9b-4e23-ab3c-058b6a6f85fb
This generated password is for development use only. Your security configuration must be updated before running your application in production.
此生成的密码仅供开发使用。在生产环境中运行应用程序之前,必须更新您的安全配置。
结论一:有配置的无生成的安全密码
结论二:无配置的有生成的安全密码
第二轮对比:登录
无配置的可以直接利用生成的安全密码,配合上默认用户user完成登录
因为有配置的没生成的安全密码,无法登录
结论一:无配置,可使用默认用户名和日志中生成的安全密码进行登录认证
结论二:有配置,目前无法进行登录
结论汇总:
结论一:有配置的无生成的安全密码
结论二:无配置的有生成的安全密码
结论三:无配置,可使用默认用户名和日志中生成的安全密码进行登录认证
结论四:有配置,目前无法进行登录
那有配置该怎么进行登录?
再认识,再总结
@Configuration //用于标记一个类为配置类,表示该类包含Bean的定义。
@EnableWebSecurity //其中一个功能:注入SecurityFilterChain
public class WebSecurityConfig {//基本配置@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());return manager;}}
作者看着源码,然后试着输入了一下,登录成功了!
username :user
password : password

我们修改user和密码试试

修改后的代码

我们去掉注册试试

启动!!!!

没区别
结论1:目前来说,还是不知道注册有啥用
结论2:我们可以通过修改InMemoryUserDetailsManager.createUser方法去自定义登录(前提:基于内存认证)
结合之前的汇总,再总结一次,修改
结论一:有配置的无生成的安全密码
结论二:无配置的有生成的安全密码
结论三:无配置,可使用默认用户名和日志中生成的安全密码进行登录认证
结论四:有配置,目前无法进行登录
结论五:目前来说,还是不知道注册有啥用
结论六:我们可以通过修改InMemoryUserDetailsManager.createUser方法去自定义登录(前提:基于内存认证)
结论一,结论二,结论三保持不变
结论四与结论六结合形成新的结论四:
有配置,可以使用InMemoryUserDetailsManager.createUser方法中的Username和password实参进行登录,也可以修改Username/password进行自定义登录
结论五不变
新结论如下:
结论一:有配置的无生成的安全密码
结论二:无配置的有生成的安全密码
结论三:无配置,可使用默认用户名和日志中生成的安全密码进行登录认证
结论四:有配置,可以使用InMemoryUserDetailsManager.createUser方法中的Username和password实参进行登录,也可以修改Username/password的实参进行自定义登录
结论五:目前来说,还是不知道注册有啥用
进一步认识,再总结
我们将对比,基本配置和默认配置,以及复习InMemoryUserDetailsManager达到进一步认识
@Configuration //用于标记一个类为配置类,表示该类包含Bean的定义。
@EnableWebSecurity //其中一个功能:注入SecurityFilterChain
public class WebSecurityConfig {//基本配置@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withDefaultPasswordEncoder().username("yanxinru").password("yanxinru233").roles("USER").build());return manager;}//默认配置@Bean@ConditionalOnMissingBean(UserDetailsService.class)InMemoryUserDetailsManager inMemoryUserDetailsManager() {String generatedPassword = "abcdefg123a48721";return new InMemoryUserDetailsManager(User.withUsername("user").password(generatedPassword).roles("ROLE_USER").build());}
}
首先,注释掉基础配置,尝试能否使用username和password里的参数进行登录
很显然无法启动程序
Error creating bean with name 'inMemoryUserDetailsManager' defined in class path resource [example/hello_security/WebSecurityConfig.class]: Failed to instantiate [org.springframework.security.provisioning.InMemoryUserDetailsManager]: Factory method 'inMemoryUserDetailsManager' threw exception with message: ROLE_USER cannot start with ROLE_ (it is automatically added)
创建在类路径资源 [example/hello_security/WebSecurityConfig.class] 中定义的名称为“inMemoryUserDetailsManager”的 Bean 时出错:无法实例化 [org.springframework.security.provisioning.InMemoryUserDetailsManager]:工厂方法“inMemoryUserDetailsManager”引发异常,并显示消息:ROLE_USER不能以 ROLE_ 开头(自动添加)
既然没办法启动,那就pass掉
那就直接进入到复习InMemoryUserDetailsManager阶段
原本想通过对比,引出InMemoryUserDetailsManager它,既然启动不了,那就不对比了,直接进入主题
InMemoryUserDetailsManager有两个功能(目前了解的)
第一个功能:对内存认证提供支持
第二个功能:管理userDetail
在刚刚的体验中,内存这一概念,恐怕不是平常定义的内存(内存大小),而是表单,不,通过体验得到是代码
@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withDefaultPasswordEncoder().username("yanxinru").password("yanxinru233").roles("USER").build());return manager;}
虽然说,代码是存储在内存中的,这也是一种说法,实际体验而言,这个内存特指这段代码,并且通过表单去验证
注意:作者对表单的定义,承载账号密码的载体
打开它的源码

它的形参来源于UserDetails

的实现

我们在基础配置中只使用了三个
回到基础配置使用的方法

通过if的结果,我们可以知道它的作用是什么,存放user,存放我们的基本配置
支持,这两个是用的真神!
内存认证通过支持,什么支持?载体支持,认证不归它管,它还有一个管理UserDetails功能,也是原因这个
总结:InMemoryUserDetailsManager的作用是提供存储用户信息的载体,目前不负责认证
汇总:
结论一:有配置的无生成的安全密码
结论二:无配置的有生成的安全密码
结论三:无配置,可使用默认用户名和日志中生成的安全密码进行登录认证
结论四:有配置,可以使用InMemoryUserDetailsManager.createUser方法中的Username和password实参进行登录,也可以修改Username/password的实参进行自定义登录
结论五:目前来说,还是不知道注册有啥用
结论六:InMemoryUserDetailsManager存放user,存放我们的基本配置
结论七:内存非内存,而是用于验证的载体,表单
相关文章:
Spring Security(maven项目) 3.0.2.9版本 --- 改
前言: 通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往…...
仿真设计|基于51单片机的温度与烟雾报警系统
目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现(protues8.7) 程序(Keil5) 全部内容 资料获取 具体实现功能 (1)LCD1602实时监测及显示温度值和烟雾浓度值; (2…...
深入剖析 CSRF 漏洞:原理、危害案例与防护
目录 前言 漏洞介绍 漏洞原理 产生条件 产生的危害 靶场练习 post 请求csrf案例 防御措施 验证请求来源 设置 SameSite 属性 双重提交 Cookie 结语 前言 在网络安全领域,各类漏洞层出不穷,时刻威胁着用户的隐私与数据安全。跨站请求伪造&…...
rust跨平台调用动态库
动态库在不同的操作系统,扩展名是不一样的,所以要做处理: static LIB: Lazy<Mutex<Option<Library>>> Lazy::new(|| Mutex::new(None));type CreateFunc unsafe extern "C" fn(*const c_char, *const c_char) -> c_int…...
buuuctf_秘密文件
题目: 应该是分析流量包了,用wireshark打开 我追踪http流未果,分析下ftp流 追踪流看看 用户 “ctf” 使用密码 “ctf” 登录。 PORT命令用于为后续操作设置数据连接。 LIST命令用于列出 FTP 服务器上目录的内容,但在此日志中未…...
课程设计|结构力学
课 程 设 计 第一部分 (结构力学) 2、两种结构在静力等效荷载作用下,内力有哪些不同?(分析比较) 1/2 1 1 1 1 1 1/2 1/4 11(1/2) 1/4 图1求解过程及结果: 轴力图: 内力计算 单位&…...
三次方根pow
给定一个浮点数n,求它的三次方根。 输入格式: 共一行,包含一个浮点数n,−10000≤n≤10000。 输出格式: 共一行,包含一个浮点数,表示问题的解。 注意,结果保留6位小数。 输入样例: 1000.00输出样例: 10.000000 …...
跟李沐学AI:视频生成类论文精读(Movie Gen、HunyuanVideo)
Movie Gen:A Cast of Media Foundation Models 简介 Movie Gen是Meta公司提出的一系列内容生成模型,包含了 3.2.1 预训练数据 Movie Gen采用大约 100M 的视频-文本对和 1B 的图片-文本对进行预训练。 图片-文本对的预训练流程与Meta提出的 Emu: Enh…...
【项目集成Husky】
项目集成Husky 安装初始化 Husky在.husky → pre-commit文件中添加想要执行的命令 安装 使用 Husky 可以帮助你在 Git 钩子中运行脚本,例如在提交代码前运行测试或格式化代码pnpm add --save-dev husky初始化 Husky npx husky init这会在项目根目录下创建一个 .hu…...
keil5如何添加.h 和.c文件,以及如何添加文件夹
1.简介 在hal库的编程中我们一般会生成如下的几个文件夹,在这几个文件夹内存储着各种外设所需要的函数接口.h文件,和实现函数具体功能的.c文件,但是有时我们想要创建自己的文件夹并在这些文件夹下面创造.h .c文件来实现某些功能,…...
2025-1-28-sklearn学习(47) (48) 万家灯火亮年至,一声烟花开新来。
文章目录 sklearn学习(47) & (48)sklearn学习(47) 把它们放在一起47.1 模型管道化47.2 用特征面进行人脸识别47.3 开放性问题: 股票市场结构 sklearn学习(48) 寻求帮助48.1 项目邮件列表48.2 机器学习从业者的 Q&A 社区 sklearn学习(47) & (48) 文章参考网站&…...
Flask数据的增删改查(CRUD)_flask删除数据自动更新
查询年龄小于17的学生信息 Student.query.filter(Student.s_age < 17) students Student.query.filter(Student.s_age.__lt__(17))模糊查询,使用like,查询姓名中第二位为花的学生信息 like ‘_花%’,_代表必须有一个数据,%任何数据 st…...
算法随笔_33: 132模式
上一篇:算法随笔_32: 移掉k位数字-CSDN博客 题目描述如下: 给你一个整数数组 nums ,数组中共有 n 个整数。132 模式的子序列 由三个整数 nums[i]、nums[j] 和 nums[k] 组成,并同时满足:i < j < k 和 nums[i] < nums[k] < nums[j…...
Linux内核中的页面错误处理机制与按需分页技术
在现代操作系统中,内存管理是核心功能之一,而页面错误(Page Fault)处理机制是内存管理的重要组成部分。当程序访问一个尚未映射到物理内存的虚拟地址时,CPU会触发页面错误异常,内核需要捕获并处理这种异常,以决定如何响应,例如加载缺失的页面、处理权限错误等。Linux内…...
【Git】使用笔记总结
目录 概述安装Git注册GitHub配置Git常用命令常见场景1. 修改文件2. 版本回退3. 分支管理 常见问题1. git add [中文文件夹] 无法显示中文问题2. git add [文件夹] 文件名中含有空格3. git add 触发 LF 回车换行警告4. git push 提示不存在 Origin 仓库5. Git与GitHub中默认分支…...
C语言中的存储类
C语言中的存储类 在C语言中,存储类是用于定义变量和函数的作用域、生命周期以及可见性的关键字。存储类决定了数据在内存中的存储位置以及它们在程序中的使用方式。本文将详细介绍C语言中的存储类,包括其类型、作用以及如何使用。 1. 存储类的类型 C语…...
DeepSeek 云端部署,释放无限 AI 潜力!
1.简介 目前,OpenAI、Anthropic、Google 等公司的大型语言模型(LLM)已广泛应用于商业和私人领域。自 ChatGPT 推出以来,与 AI 的对话变得司空见惯,对我而言没有 LLM 几乎无法工作。 国产模型「DeepSeek-R1」的性能与…...
【Qt5】声明之后快速跳转
我在网上看到的方法是ctrlL(?不是很清楚,因为我跳转不成功!) 另外一种就是鼠标点击跳转的。 首先,声明私有成员函数 此时,一般步骤应该是在构造函数里面继续,写函数的框架什么的。于…...
flowable expression和json字符串中的双引号内容
前言 最近做项目,发现了一批特殊的数据,即特殊字符",本身输入双引号也不是什么特殊的字符,毕竟在存储时就是正常字符,只不过在编码的时候需要转义,转义符是\,然而转义符\也是特殊字符&…...
新一代搜索引擎,是 ES 的15倍?
Manticore Search介绍 Manticore Search 是一个使用 C 开发的高性能搜索引擎,创建于 2017 年,其前身是 Sphinx Search 。Manticore Search 充分利用了 Sphinx,显着改进了它的功能,修复了数百个错误,几乎完全重写了代码…...
Pandas基础06(异常值的检测与过滤/抽样/常用聚合函数/数据聚合)
Pandas基础06 异常值的检测与过滤 在数据分析中,异常值(Outliers)是指与其他数据点显著不同的值。这些值可能由于数据录入错误、设备故障或极端情况而产生,因此在进行数据分析之前,需要对其进行检测与过滤。本文将介绍…...
事务01之事务机制
事务机制 文章目录 事务机制一:ACID1:什么是ACID2:MySQL是如何实现ACID的 二:MySQL事务机制综述1:手动管理事务2:事务回滚点3:事务问题和隔离机制(面试)3.1:事…...
Python-基于mediapipe,pyautogui,cv2和numpy的电脑手势截屏工具(进阶版)
前言:在我们的日常生活中,手机已经成为我们每天工作,学习,生活的一个不可或缺的部分。众所周知:为了我们的使用方便,手机里面的很多功能非常人性化,既便捷又高效,其中就有手机的截屏方式,它们花样繁多,如三指截屏,手势截屏等。那么怎么在电脑里面也实现这个功能呢?…...
@EventListener底层原理(超详细)| @TransactionalEventListener底层原理 | 事务同步
0. 举个栗子0.1. 事件监听方法0.2. 事件推送 1. EventListener注解2. EventListener标注的监听方法解析2.1. 事件监听方法处理器EventListenerMethodProcessors2.1.1. AbstractApplicationContext.invokeBeanFactoryPostProcessors2.1.2. AbstractApplicationContext.initAppli…...
NX/UG二次开发—CAM—快速查找程序参数名称
使用UF_PARAM_XXX读取或设置参数时,会发现程序中有一个INT类型参数param_index,这个就是对应程序中的参数,比如读取程序余量,则param_index = UF_PARAM_STOCK_PART,读取程序的加工坐标系则param_index = UF_PARAM_MCS等等。 你需要读取什么参数,只要只能在uf_param_indic…...
X86路由搭配rtl8367s交换机
x86软路由,买双网口就好。或者单网口主板,外加一个pcie千兆。 华硕h81主板戴尔i350-T2双千兆,做bridge下载,速度忽高忽低。 今天交换机到货,poe供电,还是网管,支持Qvlan及IGMP Snooping…...
【C++语言】卡码网语言基础课系列----5. A+B问题VIII
文章目录 练习题目AB问题VIII具体代码实现 小白寄语诗词共勉 练习题目 AB问题VIII 题目描述: 你的任务是计算若干整数的和。 输入描述: 输入的第一行为一个整数N,接下来N行每行先输入一个整数M,然后在同一行内输入M个整数。 输出…...
【LLM-agent】(task1)简单客服和阅卷智能体
note 一个完整的agent有模型 (Model)、工具 (Tools)、编排层 (Orchestration Layer)一个好的结构化 Prompt 模板,某种意义上是构建了一个好的全局思维链。 如 LangGPT 中展示的模板设计时就考虑了如下思维链:Role (角色) -> Profile(角色…...
CAP 定理的 P 是什么
分布式系统 CAP 定理 P 代表什么含义 作者之前在看 CAP 定理时抱有很大的疑惑,CAP 定理的定义是指在分布式系统中三者只能满足其二,也就是存在分布式 CA 系统的。作者在网络上查阅了很多关于 CAP 文章,虽然这些文章对于 P 的解释五花八门&am…...
RK3568使用opencv(使用摄像头捕获图像数据显示)
文章目录 一、opencv相关的类1. **cv::VideoCapture**2. **cv::Mat**3. **cv::cvtColor**4. **QImage**5. **QPixmap**总结二、代码实现一、opencv相关的类 1. cv::VideoCapture cv::VideoCapture 是 OpenCV 中用于视频捕捉的类,常用于从摄像头、视频文件、或者图像序列中捕…...
