SpringSecurity--DelegatingFilterProxy工作流程
什么是 DelegatingFilterProxy
?
DelegatingFilterProxy
是 Spring 提供的一个特殊的过滤器,它起到了桥梁的作用,可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。
为什么需要 DelegatingFilterProxy
?
通常情况下,Servlet 容器中的过滤器是由 Servlet 容器直接管理的,但这样有一些局限性,比如你不能方便地使用 Spring 的依赖注入来管理过滤器的依赖。通过使用 DelegatingFilterProxy
,你可以把过滤器放到 Spring 容器中管理,享受 Spring 提供的各种功能。
怎么理解 DelegatingFilterProxy
的工作流程?
- 配置过滤器:你在
web.xml
文件中配置了一个过滤器,但这个过滤器实际上是DelegatingFilterProxy
。 - 委托处理:
DelegatingFilterProxy
会将请求委托给 Spring 容器中定义的某个具体的过滤器(这个过滤器是一个 Spring Bean)。 - Spring 管理:这个具体的过滤器可以使用 Spring 的各种功能,比如依赖注入、事务管理等等。
示例:使用 DelegatingFilterProxy
配置 Spring Security
假设我们需要在一个 Spring 项目中使用 Spring Security 来管理权限验证。我们将通过 DelegatingFilterProxy
将 Spring Security 的过滤器配置到 Spring 容器中。
1. 配置 web.xml
在 web.xml
文件中,我们配置一个 DelegatingFilterProxy
,并指定 Spring Security 的过滤器 Bean 名称。
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><!-- 配置 DelegatingFilterProxy --><filter><filter-name>springSecurityFilterChain</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class></filter><filter-mapping><filter-name>springSecurityFilterChain</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 其他配置 -->
</web-app>
2. 配置 Spring Bean
在 Spring 的配置文件中,我们定义 UserService
和 CustomSecurityFilter
Bean,并使用依赖注入。
applicationContext.xml
示例:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"xmlns:sec="http://www.springframework.org/schema/security"xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"><!-- 配置 Spring Security --><sec:http auto-config="true"><sec:intercept-url pattern="/admin/**" access="ROLE_ADMIN" /><sec:form-login login-page="/login" default-target-url="/home" /><sec:logout logout-success-url="/login?logout" /></sec:http><sec:authentication-manager><sec:authentication-provider><sec:user-service><sec:user name="user" password="password" authorities="ROLE_USER" /><sec:user name="admin" password="password" authorities="ROLE_ADMIN" /></sec:user-service></sec:authentication-provider></sec:authentication-manager>
</beans>
这样配置后,所有的 HTTP 请求都会经过 DelegatingFilterProxy
,它会将请求委托给 Spring 容器中的 Spring Security 过滤器链,完成权限验证和安全控制
(困惑)实际上 springSecurityFilterChain
是 Spring Security 内部自动配置的一个 Bean,具体如何配置和工作如下:
1. DelegatingFilterProxy
和 springSecurityFilterChain
在使用 DelegatingFilterProxy
时,它会在 Spring 容器中查找一个名为 springSecurityFilterChain
的 Bean。这个 Bean 是由 Spring Security 自动配置的,不需要你显式地在配置中定义。Spring Security 在启动时会自动创建这个 Bean,并将它注册为过滤器链。
所以整个请求流程
-
请求到达 Servlet 容器:
- 当客户端发起请求时,Servlet 容器开始处理这个请求。
-
查找匹配的过滤器:
- Servlet 容器根据
web.xml
中的<filter-mapping>
配置来决定哪些过滤器需要应用于这个请求。在你的配置中,所有的请求都匹配/*
,因此都会经过名为customSecurityFilter
的过滤器。
- Servlet 容器根据
<filter-mapping><filter-name>customSecurityFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
调用 DelegatingFilterProxy
:
- Servlet 容器找到名为
customSecurityFilter
的过滤器,并创建DelegatingFilterProxy
的实例。此时,DelegatingFilterProxy
并不直接处理请求,而是作为一个代理来转发请求。
<filter><filter-name>customSecurityFilter</filter-name><filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
-
委托给 Spring 容器中的 Bean:
DelegatingFilterProxy
使用filter-name
(即customSecurityFilter
)来查找 Spring 容器中的同名 Bean。在 Spring 容器中,customSecurityFilter
是一个实际的过滤器 Bean。DelegatingFilterProxy
会调用 Spring 容器中的customSecurityFilter
Bean 的doFilter
方法。这样,Spring 容器中的 Bean 就可以处理请求,并利用 Spring 的依赖注入等功能。
-
执行过滤器逻辑:
customSecurityFilter
Bean 处理请求。它可以依赖于其他 Spring 管理的 Bean,比如服务层的组件等。
图解流程
- 客户端请求 → 2. Servlet 容器 → 3. 查找
DelegatingFilterProxy
→ 4.DelegatingFilterProxy
查找 Spring 容器中的customSecurityFilter
Bean → 5.customSecurityFilter
Bean 执行过滤器逻辑 → 6. 继续处理请求或返回响应
客户端请求↓
Servlet 容器↓
DelegatingFilterProxy(代理)↓
Spring 容器中的 customSecurityFilter Bean↓
执行过滤器逻辑↓
继续处理请求或返回响应
DelegatingFilterProxy
确实是通过 filter-name
来查找 Spring 容器中的同名 Bean
查找 Spring Bean:
在 DelegatingFilterProxy
的 init
方法中,它会根据 filter-name
找到 Spring 容器中的相应 Bean。这个过程包括:
- 获取过滤器名称:通过
getFilterConfig().getFilterName()
获取配置的filter-name
。 - 从 Spring 容器中获取 Bean:使用
WebApplicationContextUtils
或类似的工具从 Spring 容器中查找与filter-name
匹配的 Bean。
@Override
public void init(FilterConfig filterConfig) throws ServletException {this.filterConfig = filterConfig;String beanName = filterConfig.getFilterName();ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());this.delegate = (Filter) applicationContext.getBean(beanName);
}
-
在上面的代码中,
beanName
是从filterConfig
获取的过滤器名称,然后从 Spring 容器中获取这个 Bean。 -
委托请求处理:
在
doFilter
方法中,DelegatingFilterProxy
将请求转发给它从 Spring 容器中获得的 Bean:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if (this.delegate == null) {throw new ServletException("Delegate Filter not initialized");}this.delegate.doFilter(request, response, chain);
}
-
这里,
this.delegate
是从 Spring 容器中获取的实际过滤器 Bean,它的doFilter
方法被调用来处理请求。
总结
filter-name
:在web.xml
中配置的filter-name
用于标识DelegatingFilterProxy
要代理的 Spring Bean 名称。- Spring 容器:
DelegatingFilterProxy
使用这个名称从 Spring 容器中查找实际的过滤器 Bean。 - 委托处理:找到 Bean 后,
DelegatingFilterProxy
将请求委托给这个 Bean 来处理。
通过这些源码中的实现细节,可以确认 DelegatingFilterProxy
是如何使用 filter-name
查找和委托请求给 Spring 容器中的 Bean 的。
DelegatingFilterProxy
和普通的 Servlet 过滤器相比
普通的 Servlet 过滤器
在传统的 Servlet 过滤器中,你会直接实现 javax.servlet.Filter
接口,并在 doFilter
方法中处理请求。例如:
public class CustomFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化代码}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {// 过滤器逻辑chain.doFilter(request, response); // 继续传递请求}@Overridepublic void destroy() {// 清理资源}
}
在 web.xml
中,你会配置这个过滤器,如下:
<filter><filter-name>customFilter</filter-name><filter-class>com.example.CustomFilter</filter-class>
</filter><filter-mapping><filter-name>customFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
DelegatingFilterProxy
DelegatingFilterProxy
是 Spring 提供的一个特殊过滤器,它的工作原理略有不同。它的主要目的是将请求转发给 Spring 容器中的实际过滤器 Bean,而不是直接处理请求。DelegatingFilterProxy
实现了 javax.servlet.Filter
接口,但它的 doFilter
方法并不会直接处理请求,而是将请求委托给 Spring 管理的 Bean。
DelegatingFilterProxy
的工作流程:
-
初始化:
- 在
init
方法中,DelegatingFilterProxy
根据filter-name
从 Spring 容器中查找一个 Bean。这个 Bean 实现了javax.servlet.Filter
接口,并且是由 Spring 容器管理的。
- 在
@Override
public void init(FilterConfig filterConfig) throws ServletException {this.filterConfig = filterConfig;String beanName = filterConfig.getFilterName();ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());this.delegate = (Filter) applicationContext.getBean(beanName);
}
2.请求处理:
在 doFilter
方法中,DelegatingFilterProxy
将请求转发给 Spring 容器中的实际 Bean,而不是直接处理请求。
-
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {if (this.delegate == null) {throw new ServletException("Delegate Filter not initialized");}this.delegate.doFilter(request, response, chain); }
这里,
this.delegate
是从 Spring 容器中获取的实际过滤器 Bean,它会处理请求。 -
清理资源:
- 在
destroy
方法中,DelegatingFilterProxy
不会执行任何操作,因为它不直接持有资源。
- 在
- 普通 Servlet 过滤器:直接实现
Filter
接口,处理请求的逻辑在doFilter
方法中实现。 - 依赖注入:可以使用 Spring 的依赖注入功能来管理过滤器。
- Spring 管理:将过滤器的配置和管理转移到 Spring 容器中,享受 Spring 提供的其他功能(如事务管理、AOP)。
-
这里,
this.delegate
是从 Spring 容器中获取的实际过滤器 Bean,它会处理请求。 -
清理资源:
- 在
destroy
方法中,DelegatingFilterProxy
不会执行任何操作,因为它不直接持有资源。
- 在
- 普通 Servlet 过滤器:直接实现
Filter
接口,处理请求的逻辑在doFilter
方法中实现。 DelegatingFilterProxy
:作为一个代理,负责将请求委托给 Spring 容器中的实际过滤器 Bean,利用 Spring 的依赖注入等功能。- 依赖注入:可以使用 Spring 的依赖注入功能来管理过滤器。
- Spring 管理:将过滤器的配置和管理转移到 Spring 容器中,享受 Spring 提供的其他功能(如事务管理、AOP)。
相关文章:
SpringSecurity--DelegatingFilterProxy工作流程
什么是 DelegatingFilterProxy? DelegatingFilterProxy 是 Spring 提供的一个特殊的过滤器,它起到了桥梁的作用,可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。 为什么需要 DelegatingFilterProxy? 通常情况下&#x…...
GitHub每日最火火火项目(7.27)
1. 项目名称:meta - llama / llama3 项目介绍:这是 Meta Llama 3 的官方 GitHub 站点。目前尚不清楚该项目的具体功能和特点,但从名称推测,可能与 Llama 3 模型相关,或许涉及到模型的开发、训练或应用等方面。 项目地…...

git 学习总结
文章目录 一、 git 基础操作1、工作区2、暂存区3、本地仓库4、远程仓库 二、git 的本质三、分支git 命令总结 作者: baron 一、 git 基础操作 如图所示 git 总共有几个区域 工作区, 暂存区, 本地仓库, 远程仓库. 1、工作区 存放项目代码的地方,他有两种状态 Unm…...

《如何找到自己想做的事》
Arouse Enthusiasm, Give Scope to Skill, Explore The Essence *摘其两纸 我喜欢打篮球,并不是我真的喜欢这项运动,而是我喜欢团队竞技。我喜欢看书,并不是我真喜欢阅读,而是我想要了解世界运行逻辑。寻找热爱,探寻本…...

Vue中el的两种写法
大家好我是前端寄术区博主PleaSure乐事。今天了解到了Vue当中有关el的两种写法,记录下来与大家分享,希望对大家有所帮助。 方法一 解释 第一种方法我们直接用new创建并初始化一个新的 Vue 实例,并定义了 Vue 实例的数据对象,在给…...

ELK安装(Elasticsearch+Logstash+Kibana+Filebeat)
一、简介 1.1、软件简介 ELK其实是Elasticsearch,Logstash 和 Kibana三个产品的首字母缩写,这三款都是开源产品。 1.1.1、Elasticsearch简介 Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析…...

VScode使用Github Copilot插件时出现read ECONNREST问题的解决方法
文章目录 read ECONNREST查看是否仍是 Copilot 会员查看控制台输出网络连接问题浏览器设置问题笔者的话 read ECONNREST 最近使用 Copilot 时一直出现 read ECONNREST 问题,这个表示连接被对方重置了,就是说在读取数据时连接被关闭。 我首先怀疑是不是…...

充电桩浪涌保护方案—保障充电设施安全稳定运行的关键
在当今新能源汽车蓬勃发展的时代,充电桩作为电动汽车的“加油站”,其重要性不言而喻。然而,由于其复杂的电气环境和暴露于户外的特点,充电桩容易受到浪涌的影响。浪涌可能来自雷电、电网故障、大功率设备的启停等,对充…...

Python包管理工具pip
1、安装pip cmd管理员模式打开控制台 python -m pip install --upgrade pip 2、添加pip环境变量 pip 路径 C:\Users\1\AppData\Local\Programs\Python\Python312\Scripts...

最全国内13家DNS分享 解决网页被恶意跳转或无法打开问题
腾讯 DNS (DNSPod) 腾讯 DNS 是由 DNSPod 提供的公共免费 DNS 服务。DNSPod 已被腾讯收购,现在属于腾讯公司所有。该 DNS 服务稳定性和连通性良好,经测试在海外也可以使用。 DNSPod 提供了 IPv4、IPv6 DNS 和 DoT/DoH 服务。 IPv4 地址: 119.29.29.29…...
最新站长工具箱源码,拥有几百个功能,安装教程
最新站长工具箱源码,拥有几百个功能,安装教程 在 Docker 上运行 docker run -e LAFREGIONCN -e APPLANGzh_CN --name my-miaoda -v ~/.miaoda-docker:/root/.miaoda -d -p 0.0.0.0:39899:39899 codegentoolbox/laftools-linux-x64:latestNOTE: 默认端…...

【算法/训练】:动态规划(线性DP)
一、路径类 1. 字母收集 思路: 1、预处理 对输入的字符矩阵我们按照要求将其转换为数字分数,由于只能往下和往右走,因此走到(i,j)的位置要就是从(i - 1, j)往下走&#…...
计算巨头 Azure、AWS 和 GCP 的比较
云计算领域由三大主要参与者主导:Microsoft Azure、Amazon Web Services (AWS) 和 Google Cloud Platform (GCP)。每个平台都为希望利用云提供基础设施、平台服务等的企业提供强大的功能。在本文中,我们将深入探讨这些平台之间的差异,重点关注…...
Thinkphp5跨域问题常见的处理方法
在ThinkPHP5中,处理跨域问题通常涉及配置中间件或直接在控制器中设置响应头。以下是几种常见的解决跨域问题的方法: 1. 使用中间件处理跨域 你可以创建一个中间件来专门处理跨域请求。这个中间件会检查请求的来源,并设置相应的响应头来允许…...

Matlab编程资源库(9)数据插值与曲线拟合
一、一维数据插值 在MATLAB中,实现这些插值的函数是interp1,其调用格式为: Y1interp1(X,Y,X1,method) 函数根据X,Y的值,计算函数在X1处的值。X,Y是两个等长的已知向量,分别描述采样点和样本值,X1是一个向量…...

matplotlib的科研绘图辅助
matplotlib的科研绘图辅助 趁着暑假,与和鲸科技合作了一个python绘图的教程,作为暑期夏令营的一小部分,主要内容是介绍如何使用matplotlib、pandas、seaborn和plotnine进行医学科研绘图,感兴趣的可以通过如下地址进行访问&#x…...

C++内存管理(候捷)第五讲 笔记
GNU C对allocators的描述 new_allocator 和malloc_allocator,它们都没有特别的动作,无非底部调用operator new和malloc。它们没有用内存池 区别:::operator new是可重载的 智能型的allocator,使用内存池,分一大块然后…...

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名
文章目录 一,创建第三方服务模块thrid-party1,创建一个名为gulimall-third-party的模块2,nacos上创建third-party命名空间,用来管理这个服务的所有配置3,配置pom文件4,配置文件5,单元测试6&…...

详细介绍BIO、NIO、IO多路复用(select、poll、epoll)
BIO、NIO、IO多路复用 BIO(Blocking IO)NIO(Non-blocking IO) 同步非阻塞IOIO多路复用selectpollepoll Redis的IO多路复用 BIO(Blocking IO) 最基础的IO模型,当进行IO操作时,线程会被阻塞,直到操作完成。 比如read和write,通常IO…...

昇思25天学习打卡营第11天|xiaoyushao
今天分享ResNet50迁移学习。 在实际应用场景中,由于训练数据集不足,所以很少有人会从头开始训练整个网络。普遍的做法是,在一个非常大的基础数据集上训练得到一个预训练模型,然后使用该模型来初始化网络的权重参数或作为固定特征提…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...

Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...