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

news2025/1/10 21:35:07

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.coloradmin.cn/o/582547.html

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

相关文章

交直流混合配电网潮流计算(统一求解法)

目录 1 主要内容 算例模型 统一求解法迭代方程 算法流程图 2 部分代码 3 程序结果 4 程序链接 1 主要内容 该程序为matlab代码&#xff0c;采用统一求解法对交直流混合配电网进行潮流计算&#xff0c;统一迭代法又称统一求解法&#xff0c;其思路是将混联系统中的交流网…

FPGA串口发送数据

module Uart(input clk, //H3input rst, //F10output reg TX //串口发送脚M12 );reg[9:0] buffer 10b1_1100_1010_0; //接收方&#xff1a;0XCA parameter SND_T 5208; //9600bps reg [15:0] cnt 0; //数据宽度计数 always (posedge clk or negedge rst) beginif(!rs…

Unity游戏优化指南大全(持续更新中!)

Unity游戏优化指南大全 三个官方优化提示&#xff1a; 性能和优化 (Performance and Optimization) - 关于性能分析器以及性能和优化技巧的 Unity 学习教程。Best practices for performance optimization in Unity - 优化应用程序的最佳实践指南。Ultimate guide to profili…

【gstreamer】入门介绍

概述 GStreamer是一个基于流媒体的框架&#xff0c;是一个开放源代码的多媒体框架&#xff0c;用于创建音频和视频处理应用程序。它是一个运行在多个操作系统上的跨平台框架&#xff0c;支持多种不同的多媒体格式。 GStreamer框架的核心是基于插件的体系结构&#xff0c;插件…

GEE:绘制一个点的时间序列折线图,并且显示所有可用影像(逐日合成影像集合)

作者:CSDN @ _养乐多_ 本文将介绍在 Google Earth Engine (GEE)平台上,对“COPERNICUS/S5P/NRTI/L3_CO”数据集逐日合成,并可视化所有影像,根据逐日合成数据集绘制指定点的时间序列折线图。 图1 每天合成图像可视化 图2 一个点的每天合成时间序列折线图 文章目录 一、代…

VWS型振弦式应变计安装埋设时要注意什么

VWS型振弦式应变计是一种常见的应变测量设备&#xff0c;它是通过将振弦安装在被测结构上来实现应变测量。南京峟思专业的应变计生产厂家提醒大家&#xff0c;在安装和埋设VWS型振弦式应变计时&#xff0c;需要注意以下事项&#xff1a; 南京峟思工程仪器振弦式应变计 ​​​​…

84.Rem和max-width如何工作

max-width 首先我们先看普通的width是什么样的效果&#xff01; 首先给个测试的div <div class"test">TEST</div>● 然后CSS给定一个宽度 .test {width: 1000px;background-color: red;padding: 100px; }如上图&#xff0c;不管你的浏览器窗口如何改变…

记一次处理Spring-boot使用dubbo类型转换失败的问题

第一步、使用父类接收子类&#xff0c;类型转换失败&#xff0c;猜测是不是父子类不能接收&#xff0c;&#xff08;应该不可能&#xff0c;但还是试下&#xff09;&#xff1b; 第二步、使用同一个类接收&#xff0c;还是类型转换失败&#xff1b; com.book.common.result.Res…

将 Rust 程序编译为 WebAssembly

Rust 笔记、WebAssembly 将 Rust 程序编译为 WebAssembly 的知识与实践 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263?spm1001.2101.3001.5343 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blo…

浅谈安科瑞霍尔传感器在转速测量中的选型与应用

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘 要&#xff1a;在现代工业生产中存在许多需要转速测量的方面&#xff0c;针对转速测量方法落后、只能进行接触式测量等问题&#xff0c;提出把霍尔传感器应用于工业生产中 , 利用霍尔效应测量转速&#xff0c;具有动…

【linux解压和打包文件】

TOC 打包成zip文件 指令 zip zip -r -q -o html.zip html/ -r 参数表示递归打包包含子目录的全部内容&#xff0c;-q 参数表示为安静模式&#xff0c;即不向屏幕输出信息&#xff0c;-o 表示输出文件&#xff0c;需在其后紧跟打包输出文件名。解压zip文件 1.unzip -q …

数字化时代,企业面临哪些共同的挑战?

在这种全新的社会、商业环境下&#xff0c;各行各业的企业都开始寻求探索新的商业模式&#xff0c;通过转型适应当前时代的转变&#xff0c;促进业务健康持续的发展。所以数字化成为了企业进行转型的工具&#xff0c;也成为了众多领域内企业对未来的共识。 一、管理挑战 ●经…

C++服务器框架开发3——协程与线程的简单理解/并发与并行

该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见&#xff1a;[C高级教程]从零开始开发服务器框架(sylar) 上一篇&#xff1a;C服务器框架开发2——头文件memory/typedef C服务器框架开发3——协程与线程的简单理解/并发与并行 目前进度协程与线程的简…

【基于容器的部署、扩展和管理】3.1 容器编排系统和Kubernetes集群的构建

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 3.1 基于容器的部署、扩展和管理 3.1.1 容器介绍3.1.2 容器编排系统和Kubernetes集群的构建3.1.2.1 Kubernetes 集群3.1.2.2 容器编排系统 3.1.3 Kubernetes 集…

MySQL — 锁

文章目录 锁0、概述一、全局锁1.1 概述1.2 语法1.3 一致性数据备份1.4 问题 二、表级锁2.1 表锁2.2 元数据锁2.3 意向锁 三、行级锁3.1 概述3.2 行锁3.3 间隙锁 与 临建锁 锁 0、概述 锁是计算机协调多个进程和线程并发访问某一资源的机制。 ​ 在数据库中&#xff0c;除传统…

5.5G,通信产业下一个分水岭?

通信领域的变化日新月异&#xff0c;在5G商用渐次铺开之后&#xff0c;5.5G比6G先行到来。 5月28日获悉&#xff0c;近日北京移动首个5G-A实验基站在昌平区的国际信息港建设开通&#xff0c;引发业内关注。业内观点认为&#xff0c;5.5G是5G和6G之间的过渡“台阶”&#xff0c;…

阿秀离职了

小伙伴们大家好&#xff0c;我是阿秀。 是的&#xff0c;我从字节离职了&#xff0c;从抖音研发大部门离职了。 我从21年6月份毕业后就一直在字节跳动抖音这边工作&#xff0c;到现在差不多已经 2 年时间了&#xff0c;两年时光如白马过隙一晃而过&#xff0c;时间真的很快。 天…

Matlab与ROS(1/2)---ros1_bridge(八)

0. 简介 众所周知&#xff0c;ROS 2是具有不同架构的ROS的更新版本。这两个网络是分开的&#xff0c;在ROS和ROS 2的节点之间没有直接的通信。而ros1_bridge包则是提供了一个网桥&#xff0c;可以在ROS和ROS 2之间交换消息。桥接器管理所需的所有转换&#xff0c;并在两个网络…

【源码篇】基于SpringBoot+Vue的学生选课管理系统

1、项目介绍 基于SpringBootVue的学生选课管理系统采用前后端分离的架构方式&#xff0c;系统分为管理员、老师、学生等三种角色&#xff0c;权限分配如下 管理员拥有所有权限 学生管理&#xff1a;可以对所有学生进行管理操作&#xff08;新增学生、修改学生、删除学生&…

【Netty】一行简单的writeAndFlush都做了哪些事(十八)

文章目录 前言一、源码分析1.1 ctx.writeAndFlush 的逻辑1.2 writeAndFlush 源码1.3 ChannelOutBoundBuff 类1.4 addMessage 方法1.5 addFlush 方法1.6 AbstractNioByteChannel 类 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设…