【深入浅出Spring Security(二)】Spring Security的实现原理

Spring Security的实现原理

  • 一、实现原理
  • 二、内置Filter以及默认加载的Filter
  • 三、自动配置分析(SpringBootWebSecurityConfiguration)
    • @ConditionalOnMissingBean
  • 四、自己配置SecurityFilterChain

一、实现原理

在 Spring Security 中,认证、授权等功能都是基于过滤器来完成的。开发者所见到的 Spring Security 提供的功能,都是通过这些过滤器来实现的,这些过滤器按照既定的优先级排列,最终形成一个过滤器链。当然,开发者也可以自己定义过滤器,并通过@Order注解去调整自定义过滤器在过滤器链中的位置。

需要注意的是,默认过滤器并不是直接放在 Web 项目的原生过滤器链中(即不是JavaWeb中的filter), 而是通过一个 FilterChainProxy 来统一管理。Spring Security中的过滤器链通过 FilterChainProxy 嵌入到 Web 项目的原生过滤器链中

在这里插入图片描述
在 Spring Security 中,像上图中嵌入的过滤链不仅仅只有一个,可能会有多个,当存在多个过滤器链时,多个过滤器链之间要指定优先级,当请求到达后,会从 FilterChainProxy 进行分发,先和哪个过滤器链匹配上,就用哪个过滤器链进行处理。当系统中存在多个不同的认证体系时,那么使用多个过滤器链就非常有效。

在这里插入图片描述
FilterChainProxy 作为一个顶层管理者,将统一管理 Security Filter。FilterChainProxy 本身将通过 Spring 框架提供的 DelegatingFilterProxy 整合到原生过滤器链中。

在这里插入图片描述

二、内置Filter以及默认加载的Filter

下面表格是默认加载的 Filter(这里的 Filter 都不是原始的 Web Filter),加载顺序是按下表从上而下进行的。

默认加载Filter过滤器作用是否加载
WebAsyncManagerIntegrationFilter将 WebAsyncManager 与SpringSecurity上下文集成YES
SecurityContextPersistenceFilter在处理请求之前,将安全信息加载到SecurityContextHolder中YES
HeaderWriterFilter处理头信息加入响应中YES
CsrfFilter处理CSRF攻击YES
LogoutFilter处理注销登录YES
UsernamePasswordAuthenticationFilter处理表单认证YES
DefaultLoginPageGeneratingFilter配置默认登录页面YES
DefaultLogoutPageGeneratingFilter配置默认注销页面YES
BasicAuthenticationFilter处理 HttpBasic 登录YES
RequestCacheAwareFilter处理请求缓存YES
SecurityContextHolderAwareRequestFilter包装原始请求YES
AnoymousAuthenticationFilter配置匿名认证YES
SessionManagementFilter处理Session并发问题YES
ExceptionTraslationFilter处理认证/授权中的异常YES

加载顺序和上面表一致,通过调试也可以发现(其中第一个不属于内置的Filter,而是自定义的,用来禁用URL进行编码,而最后一个是拦截器并非过滤器,剩下的与上表对应):

在这里插入图片描述

下面俩图总结了默认加载的和未默认加载的Spring Security中的过滤器。
在这里插入图片描述
在这里插入图片描述可以看出,Spring Security 提供了 30 多个过滤器。默认情况下 Spring Boot 在对 Spring Security 进行自动化配置时(SpringBoot Auto Configuration),会创建一个名为 SpringSecurityFilterChain 的过滤器链对象,并注入到 Spring 容器中,这个过滤器链将负责所有的安全管理,包括用户认证、授权、重定向到登录页面等。

三、自动配置分析(SpringBootWebSecurityConfiguration)

下面 SecurityFilterChain 自动配置的具体含义:让所有资源都必须经过认证,通过表单和Basic认证。

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
class SpringBootWebSecurityConfiguration {


/*
如果用户指定他们自己的WebSecurityConfigurerAdapter
或SecurityFilterChain bean,这将完全取消
,并且用户应该指定他们想要配置的所有位作为自定义安全配置的一部分。
*/
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnDefaultWebSecurity
	static class SecurityFilterChainConfiguration {

		@Bean
		@Order(SecurityProperties.BASIC_AUTH_ORDER)
		SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
			http.authorizeRequests()
			.anyRequest()
			.authenticated();// 这表示所有请求都必须认证
			
			http.formLogin();// 开启表单认证
			http.httpBasic();// 开启basic认证
			return http.build();
		}

	}

	/**
	 * Configures the {@link ErrorPageSecurityFilter}.
	 */
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(WebInvocationPrivilegeEvaluator.class)
	@ConditionalOnBean(WebInvocationPrivilegeEvaluator.class)
	static class ErrorPageSecurityFilterConfiguration {

		@Bean
		FilterRegistrationBean<ErrorPageSecurityFilter> errorPageSecurityFilter(ApplicationContext context) {
			FilterRegistrationBean<ErrorPageSecurityFilter> registration = new FilterRegistrationBean<>(
					new ErrorPageSecurityFilter(context));
			registration.setDispatcherTypes(DispatcherType.ERROR);
			return registration;
		}

	}


	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(name = BeanIds.SPRING_SECURITY_FILTER_CHAIN)
	@ConditionalOnClass(EnableWebSecurity.class)
	@EnableWebSecurity
	static class WebSecurityEnablerConfiguration {

	}

}

如果用户指定了他们自己的配置,那这个 SecurityFilterChain 配置就会按用户指定的来。

@ConditionalOnMissingBean

实现效果是源于 SpringBoot 内的 @ConditionalOnMissingBean 注解,用于根据是否存在指定类型的Bean来决定是否创建或注册一个Bean。如果存在指定类型的Bean,则不会创建或注册该Bean;否则,会创建或注册该Bean。

@ConditionalOnDefaultWebSecurity =》
元注解 @Conditional(DefaultWebSecurityCondition.class) =》

@ConditionalOnClass({ SecurityFilterChain.class, 
					HttpSecurity.class })
	static class Classes {

	}

@ConditionalOnMissingBean({
			org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.class,
			SecurityFilterChain.class })

上述源码表示使用默认配置的条件有俩条:

  1. 类路径得有 SecurityFilterChain 、HttpSecurity (注意是类路径,容器内有对SecurityFilterChain的默认实现类,但没有交给容器管理,所以也是满足条件2的);
  2. 容器内不得有 SecurityFilterChain 和 WebSecurityConfigurerAdapter 实例对象;

即容器中没有 WebSecurityConfigurerAdapter 对象或 SecurityFilterChain 对象,就会按默认配置来,有的话就按用户自定义来。

但是在Spring Security 5.7.8 这个新版本中已经把继承 WebSecurityConfigurerAdapter 这种方式给弃用了,而是去使用@EnableWebSecurity注解。原因是这样可以更加灵活地配置安全策略,并且能够更好地与Spring Boot等框架进行集成。比如使用 @EnableGlobalMethodSecurity 注解进行进一步的安全配置。

四、自己配置SecurityFilterChain

在 5.7.8 之后已经开始推荐使用 @EnableWebSecurity 注解的形式进行开发了,而 WebSecurityConfigurerAdapter 这个类已经被弃用。新版配置如下:

@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(@Autowired HttpSecurity http) throws Exception {
        return http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .and()
                .build();
    }

}

注意:可以不用在写@Configuration注解去表明这是配置类了,这是因为@EnableWebSecurity 上被@Configuration 元注解标识了。

在这里插入图片描述

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

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

相关文章

高压功率放大器ATA4014VS高压功率放大器HSA42014

高压功率放大器ATA4014VS高压功率放大器HSA42014 一、企业背景&#xff1a; Aigtek是一家来自中国的专业从事测量仪器研发、生产和销售的高科技企业。公司主要研发和生产功率放大器、功率放大器模块、功率信号源、计量校准源等产品。核心团队主要是来自西安交通大学及西北工业大…

LiangGaRy-学习笔记-Day17

1、磁盘的介绍 自动分区、手工分区、命令工具分区 1.1、磁盘分类 根据介质来区分&#xff1a; 机械硬盘和固态硬盘 通过盘大小&#xff1a; 3.5英寸和2.5英寸 通过接口分类&#xff1a; SAS、SATA、FC scisi 根据功能&#xff1a; 桌面和企业级别 1.2、磁盘类型 HD…

数据在内存中的存储(1)——整形

目录 1、数据类型介绍 1.1、类型的基本归类 整形家族 浮点数家族 指针类型 空类型 构造类型 2、整形在内存中的存储 2.1、原码、反码、补码 2.2、大小端介绍 2.3、有符号与无符号 2.4、练习 例一 例二 例三 例四 例五 1、数据类型介绍 我们先来简单了解一下我们前面所学的基…

STM32F4_软件模拟SPI

目录 1. 硬件连接 2. SPI通讯协议 3. W25Q64 简介 4. 程序详解 4.1 main.c 4.2 SPI.c 4.3 SPI.h 4.4 W25Q128.c 4.5 W25Q128.h 4.6 OLED.c 4.7 OLED.h 4.8 OLED_Font.h 5. 实验结果 我们都知道&#xff0c;SPI 和 IIC 一样&#xff0c;都可以通过硬件方式和软件方…

Phaser笔记-精灵(sprite)的使用

如下&#xff1a; 使用逻辑如下&#xff1a; ①设置好physics&#xff1b; ②将资源添加到spritesheet&#xff1b; ③在physics中添加sprite&#xff1b; ④创建anims&#xff1b; ⑤播放anims&#xff1b; 完整代码如下&#xff1a; import phaser;class PlayGame exte…

Linux 系统上的库文件生成与使用

1.库文件 库是一组预先编译好的方法的集合。Linux系统存储的库的位置一般在&#xff1a;/lib 和 /usr/lib。 在 64 位的系统上有些库也可能被存储在/usr/lib64 下。库的头文件一般会被存储在 /usr/include 下或其子目录下。 库有两种&#xff0c;一种是静态库&#xff0c;其…

springboot + vue3实现视频播放Demo(video.js Vue3-video-play视频播放器)

文章目录 学习链接前言ffmpeg安装ffmpeg配置环境变量分割视频文件 后台配置WebConfig 前端代码video.js示例安装依赖视频播放组件效果 Vue3-video-play示例安装依赖main.js中使用视频播放组件效果 学习链接 ffmpeg官网 长时长视频java存储及vue播放解决方法 【 攻城略地 】vue…

Packet Tracer - 配置区域策略防火墙

Packet Tracer - 配置区域策略防火墙 拓扑 地址表 设备 接口 IP地址 子网掩码 默认网关 交换机端口 R1 F0/1 192.168.1.1 255.255.255.0 N/A S1 F0/2 S0/3/0 (DCE) 10.1.1.1 255.255.255.252 N/A N/A R2 S0/3/0 10.1.1.2 255.255.255.252 N/A N/A S0/3…

C++ priority_queue

C priority_queue &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;C &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容讲解了优先队列的对应接口的使用 文章目录…

[GUET-CTF2019]number_game[数独]

目录 题目 学到的知识点&#xff1a; 题目 在buu上看到了一道数独题&#xff0c;没见过&#xff0c;记录一下 下载附件&#xff0c;查壳&#xff0c;无壳&#xff0c;在IDA中打开&#xff0c;直接找到主函数 unsigned __int64 __fastcall main(int a1, char **a2, char **a3…

工程swift与OC混编改造

最近公司项目准备引入swift&#xff0c;由于目前工程已经完成了组件化不再是简单的单仓工程&#xff0c;所以需要进行混编改造。下面记录一下自己对工程进行混编改造的思考以及过程。 混编原理 看了很多文档&#xff0c;比较少有讲混编原理的&#xff0c;这里简单介绍一下语言…

springboot+springsecurity+jwt+elementui图书管理系统

​​图书管理系统​​ 关注公号&#xff1a;java大师&#xff0c;回复“图书”&#xff0c;获取源码 一、springboot后台 1、mybatis-plus整合 1.1添加pom.xml <!--mp逆向工程 --><dependency><groupId>org.projectlombok</groupId><artifactId&…

子串--子字符串 0528

210102 201012 A1A2…An An…A2A1 如何做&#xff0c; 翻转的是21&#xff0c;因为2>1; 翻转的是210&#xff0c;因为2>0; 翻转的是2101&#xff0c;因为2>1&#xff1b; 翻转的是21010&#xff0c;因为2>0&#xff1b; 翻转的是210102&#xff0c;因为22且1&…

2023-05-29 用 fltk gui库编写一个打字练习程序

用 fltk gui库编写一个打字练习程序 前言一、FLTK GUI 库二、使用步骤1.引入库2.使用代码 总结 前言 给孩子练习键盘打字, 发现终端还是欠点意思, 研究了一下gui, 最终用 fltk库弄了一个. 对于没有接触过gui的人, 发现, 编程的逻辑和终端区别很大, 很繁琐, 可能需要适应适应,…

0基础学习VR全景平台篇第32章:场景功能-嵌入视频

大家好&#xff0c;欢迎观看蛙色VR官方系列——后台使用课程&#xff01; 一、本功能将用在哪里&#xff1f; 嵌入功能可对VR全景作品嵌入【图片】【视频】【文字】【标尺】四种不同类型内容&#xff1b; 本次主要带来视频类型的介绍&#xff0c;通过嵌入视频功能&#xff0c;…

Go语言并发

Go语言并发学习目标 出色的并发性是Go语言的特色之一 • 理解并发与并行• 理解进程和线程• 掌握Go语言中的Goroutine和channel• 掌握select分支语句• 掌握sync包的应用 并发与并行 并发与并行的概念这里不再赘述, 可以看看之前java版写的并发实践; 进程和线程 程序、进程…

腾讯云服务器常用端口号大全以及端口开启方法

腾讯云服务器常用端口号如80、21、22、8080等端口&#xff0c;出于安全考虑一些常用端口默认是关闭的&#xff0c;腾讯云服务器端口如何打开呢&#xff1f;云服务器CVM在安全组中开启端口&#xff0c;轻量应用服务器在防火墙中可以打开端口&#xff0c;腾讯云百科来详细说下腾讯…

在云服务器上部署简单的聊天机器人网站(源1.0接口版)

诸神缄默不语-个人CSDN博文目录 又不是不能用.jpg http://47.113.197.198:8000/chat 集成代码可参考&#xff1a;花月与剑/scholar_ease 之所以先用源1.0&#xff0c;一是因为我API都申请了&#xff0c;不用白不用&#xff1b;二是因为源1.0可以直接用国内网络连接&#xf…

Vue登录界面精美模板分享

文章目录 &#x1f412;个人主页&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a;&#x1f380;源码如下&#xff1a; &#x1f412;个人主页 &#x1f3c5;Vue项目常用组件模板仓库 &#x1f4d6;前言&#xff1a; 本篇博客主要提供vue组件之登陆组件源码…

idea连接Linux服务器

一、 介绍 配置idea的ssh会话和sftp可以实现对linux远程服务器的访问和文件上传下载&#xff0c;是替代Xshell的理想方式。这样我们就能在idea里面编写文件并轻松的将文件上传到linux服务器中。而且还能远程编辑linux服务器上的文件。掌握并熟练使用&#xff0c;能够大大提高我…
最新文章