Spring Security(maven项目) 3.0.2.9版本 --- 改

news2025/4/21 14:49:21
前言:

通过实践而发现真理,又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识,又从理性认识而能动地指导革命实践,改造主观世界和客观世界。实践、认识、再实践、再认识,这种形式,循环往复以至无穷,而实践和认识之每一循环的内容,都比较地进到了高一级的程度。

本期目标:

针对上一期的java配置进行修改,优化可读性,易上手程度

正片:

Spring Security Java配置

基于Security Filter Chain,我们对配置进行了分类

                        第一类:Security Filter配置(客体)

                        第二类:Security Filter Chain配置(主体)

基本结构

第一类配置模板:

@Configuration          //用于标记一个类为配置类,表示该类包含Bean的定义。
@EnableWebSecurity      //其中一个功能:注入SecurityFilterChain
public class WebSecurityConfig {
        
        //自定义Security Filter 配置......

}

第二类配置模板:

public class SecurityWebApplicationInitializer
        extends AbstractAnnotationConfigDispatcherServletInitializer {


    @Override
    protected Class<?>[] getRootConfigClasses() {
        // 注册Security Filter Chain
        // 话口号内公式:带有@EnableWebSecurity的类
        // 一般情况,一个配置可以完成全部功能
        return new Class[]{WebSecurityConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[0];
    }

    @Override
    protected 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 {

    //基本配置
    @Bean
    public 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 {

    //基本配置
    @Bean
    public 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 {

    //基本配置
    @Bean
    public 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

在刚刚的体验中,内存这一概念,恐怕不是平常定义的内存(内存大小),而是表单,不,通过体验得到是代码

 @Bean
    public 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,存放我们的基本配置

结论七:内存非内存,而是用于验证的载体,表单

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

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

相关文章

仿真设计|基于51单片机的温度与烟雾报警系统

目录 具体实现功能 设计介绍 51单片机简介 资料内容 仿真实现&#xff08;protues8.7&#xff09; 程序&#xff08;Keil5&#xff09; 全部内容 资料获取 具体实现功能 &#xff08;1&#xff09;LCD1602实时监测及显示温度值和烟雾浓度值&#xff1b; &#xff08;2…

深入剖析 CSRF 漏洞:原理、危害案例与防护

目录 前言 漏洞介绍 漏洞原理 产生条件 产生的危害 靶场练习 post 请求csrf案例 防御措施 验证请求来源 设置 SameSite 属性 双重提交 Cookie 结语 前言 在网络安全领域&#xff0c;各类漏洞层出不穷&#xff0c;时刻威胁着用户的隐私与数据安全。跨站请求伪造&…

buuuctf_秘密文件

题目&#xff1a; 应该是分析流量包了&#xff0c;用wireshark打开 我追踪http流未果&#xff0c;分析下ftp流 追踪流看看 用户 “ctf” 使用密码 “ctf” 登录。 PORT命令用于为后续操作设置数据连接。 LIST命令用于列出 FTP 服务器上目录的内容&#xff0c;但在此日志中未…

课程设计|结构力学

课 程 设 计 第一部分 &#xff08;结构力学&#xff09; 2、两种结构在静力等效荷载作用下&#xff0c;内力有哪些不同&#xff1f;&#xff08;分析比较&#xff09; 1/2 1 1 1 1 1 1/2 1/4 11(1/2) 1/4 图1求解过程及结果&#xff1a; 轴力图&#xff1a; 内力计算 单位&…

跟李沐学AI:视频生成类论文精读(Movie Gen、HunyuanVideo)

Movie Gen&#xff1a;A Cast of Media Foundation Models 简介 Movie Gen是Meta公司提出的一系列内容生成模型&#xff0c;包含了 3.2.1 预训练数据 Movie Gen采用大约 100M 的视频-文本对和 1B 的图片-文本对进行预训练。 图片-文本对的预训练流程与Meta提出的 Emu: Enh…

keil5如何添加.h 和.c文件,以及如何添加文件夹

1.简介 在hal库的编程中我们一般会生成如下的几个文件夹&#xff0c;在这几个文件夹内存储着各种外设所需要的函数接口.h文件&#xff0c;和实现函数具体功能的.c文件&#xff0c;但是有时我们想要创建自己的文件夹并在这些文件夹下面创造.h .c文件来实现某些功能&#xff0c;…

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) 文章参考网站&…

DeepSeek 云端部署,释放无限 AI 潜力!

1.简介 目前&#xff0c;OpenAI、Anthropic、Google 等公司的大型语言模型&#xff08;LLM&#xff09;已广泛应用于商业和私人领域。自 ChatGPT 推出以来&#xff0c;与 AI 的对话变得司空见惯&#xff0c;对我而言没有 LLM 几乎无法工作。 国产模型「DeepSeek-R1」的性能与…

【Qt5】声明之后快速跳转

我在网上看到的方法是ctrlL&#xff08;&#xff1f;不是很清楚&#xff0c;因为我跳转不成功&#xff01;&#xff09; 另外一种就是鼠标点击跳转的。 首先&#xff0c;声明私有成员函数 此时&#xff0c;一般步骤应该是在构造函数里面继续&#xff0c;写函数的框架什么的。于…

flowable expression和json字符串中的双引号内容

前言 最近做项目&#xff0c;发现了一批特殊的数据&#xff0c;即特殊字符"&#xff0c;本身输入双引号也不是什么特殊的字符&#xff0c;毕竟在存储时就是正常字符&#xff0c;只不过在编码的时候需要转义&#xff0c;转义符是\&#xff0c;然而转义符\也是特殊字符&…

新一代搜索引擎,是 ES 的15倍?

Manticore Search介绍 Manticore Search 是一个使用 C 开发的高性能搜索引擎&#xff0c;创建于 2017 年&#xff0c;其前身是 Sphinx Search 。Manticore Search 充分利用了 Sphinx&#xff0c;显着改进了它的功能&#xff0c;修复了数百个错误&#xff0c;几乎完全重写了代码…

事务01之事务机制

事务机制 文章目录 事务机制一&#xff1a;ACID1&#xff1a;什么是ACID2&#xff1a;MySQL是如何实现ACID的 二&#xff1a;MySQL事务机制综述1&#xff1a;手动管理事务2&#xff1a;事务回滚点3&#xff1a;事务问题和隔离机制&#xff08;面试&#xff09;3.1&#xff1a;事…

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软路由&#xff0c;买双网口就好。或者单网口主板&#xff0c;外加一个pcie千兆。 华硕h81主板戴尔i350-T2双千兆&#xff0c;做bridge下载&#xff0c;速度忽高忽低。 今天交换机到货&#xff0c;poe供电&#xff0c;还是网管&#xff0c;支持Qvlan及IGMP Snooping&#xf…

【LLM-agent】(task1)简单客服和阅卷智能体

note 一个完整的agent有模型 (Model)、工具 (Tools)、编排层 (Orchestration Layer)一个好的结构化 Prompt 模板&#xff0c;某种意义上是构建了一个好的全局思维链。 如 LangGPT 中展示的模板设计时就考虑了如下思维链&#xff1a;Role (角色) -> Profile&#xff08;角色…

ZZNUOJ(C/C++)基础练习1021——1030(详解版)

目录 1021 : 三数求大值 C语言版 C版 代码逻辑解释 1022 : 三整数排序 C语言版 C版 代码逻辑解释 补充 &#xff08;C语言版&#xff0c;三目运算&#xff09;C类似 代码逻辑解释 1023 : 大小写转换 C语言版 C版 1024 : 计算字母序号 C语言版 C版 代码逻辑总结…

2025 年,链上固定收益领域迈向新时代

“基于期限的债券市场崛起与 Secured Finance 的坚定承诺” 2025年&#xff0c;传统资产——尤其是股票和债券——大规模涌入区块链的浪潮将创造历史。BlackRock 首席执行官 Larry Fink 近期在彭博直播中表示&#xff0c;代币化股票和债券将逐步融入链上生态&#xff0c;将进一…

基于互联网+智慧水务信息化整体解决方案

智慧水务的概述与发展背景 智慧水务是基于互联网、云计算、大数据、物联网等先进技术&#xff0c;对水务行业的工程建设、生产管理、管网运营、营销服务及企业综合管理等业务进行全面智慧化管理的创新模式。它旨在解决水务企业分散经营、管理水平不高、投资不足等问题。 水务…

FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型

void initUser(User user); } 2、执行命令./gradlew assembleDebug&#xff0c;生成IUserServiceStub类和fidl.json文件 3、打开通道&#xff0c;向Flutter公开方法 FidlChannel.openChannel(getFlutterEngine().getDartExecutor(), new IUserServiceStub() { Override void…

文件读写操作

写入文本文件 #include <iostream> #include <fstream>//ofstream类需要包含的头文件 using namespace std;void test01() {//1、包含头文件 fstream//2、创建流对象ofstream fout;/*3、指定打开方式&#xff1a;1.ios::out、ios::trunc 清除文件内容后打开2.ios:…