当前位置: 首页 > news >正文

SpringSecurity--DelegatingFilterProxy工作流程

什么是 DelegatingFilterProxy

DelegatingFilterProxy 是 Spring 提供的一个特殊的过滤器,它起到了桥梁的作用,可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。

为什么需要 DelegatingFilterProxy

通常情况下,Servlet 容器中的过滤器是由 Servlet 容器直接管理的,但这样有一些局限性,比如你不能方便地使用 Spring 的依赖注入来管理过滤器的依赖。通过使用 DelegatingFilterProxy,你可以把过滤器放到 Spring 容器中管理,享受 Spring 提供的各种功能。

怎么理解 DelegatingFilterProxy 的工作流程?

  1. 配置过滤器:你在 web.xml 文件中配置了一个过滤器,但这个过滤器实际上是 DelegatingFilterProxy
  2. 委托处理DelegatingFilterProxy 会将请求委托给 Spring 容器中定义的某个具体的过滤器(这个过滤器是一个 Spring Bean)。
  3. 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 的配置文件中,我们定义 UserServiceCustomSecurityFilter 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. DelegatingFilterProxyspringSecurityFilterChain

在使用 DelegatingFilterProxy 时,它会在 Spring 容器中查找一个名为 springSecurityFilterChain 的 Bean。这个 Bean 是由 Spring Security 自动配置的,不需要你显式地在配置中定义。Spring Security 在启动时会自动创建这个 Bean,并将它注册为过滤器链。

 所以整个请求流程

  • 请求到达 Servlet 容器

    • 当客户端发起请求时,Servlet 容器开始处理这个请求。
  • 查找匹配的过滤器

    • Servlet 容器根据 web.xml 中的 <filter-mapping> 配置来决定哪些过滤器需要应用于这个请求。在你的配置中,所有的请求都匹配 /*,因此都会经过名为 customSecurityFilter 的过滤器。
<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>
  1. 委托给 Spring 容器中的 Bean

    • DelegatingFilterProxy 使用 filter-name(即 customSecurityFilter)来查找 Spring 容器中的同名 Bean。在 Spring 容器中,customSecurityFilter 是一个实际的过滤器 Bean。
    • DelegatingFilterProxy 会调用 Spring 容器中的 customSecurityFilter Bean 的 doFilter 方法。这样,Spring 容器中的 Bean 就可以处理请求,并利用 Spring 的依赖注入等功能。
  2. 执行过滤器逻辑

    • customSecurityFilter Bean 处理请求。它可以依赖于其他 Spring 管理的 Bean,比如服务层的组件等。

图解流程

  1. 客户端请求 → 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

DelegatingFilterProxyinit 方法中,它会根据 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);
}
  1. 这里,this.delegate 是从 Spring 容器中获取的实际过滤器 Bean,它的 doFilter 方法被调用来处理请求。

总结

  1. filter-name:在 web.xml 中配置的 filter-name 用于标识 DelegatingFilterProxy 要代理的 Spring Bean 名称。
  2. Spring 容器DelegatingFilterProxy 使用这个名称从 Spring 容器中查找实际的过滤器 Bean。
  3. 委托处理:找到 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 的工作流程

  1. 初始化

    • 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&#xff1f; DelegatingFilterProxy 是 Spring 提供的一个特殊的过滤器&#xff0c;它起到了桥梁的作用&#xff0c;可以让你在 Spring 容器中管理 Servlet 容器中的过滤器。 为什么需要 DelegatingFilterProxy&#xff1f; 通常情况下&#x…...

GitHub每日最火火火项目(7.27)

1. 项目名称&#xff1a;meta - llama / llama3 项目介绍&#xff1a;这是 Meta Llama 3 的官方 GitHub 站点。目前尚不清楚该项目的具体功能和特点&#xff0c;但从名称推测&#xff0c;可能与 Llama 3 模型相关&#xff0c;或许涉及到模型的开发、训练或应用等方面。 项目地…...

git 学习总结

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

《如何找到自己想做的事》

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

Vue中el的两种写法

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

ELK安装(Elasticsearch+Logstash+Kibana+Filebeat)

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

VScode使用Github Copilot插件时出现read ECONNREST问题的解决方法

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

充电桩浪涌保护方案—保障充电设施安全稳定运行的关键

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

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 已被腾讯收购&#xff0c;现在属于腾讯公司所有。该 DNS 服务稳定性和连通性良好&#xff0c;经测试在海外也可以使用。 DNSPod 提供了 IPv4、IPv6 DNS 和 DoT/DoH 服务。 IPv4 地址: 119.29.29.29…...

最新站长工具箱源码,拥有几百个功能,安装教程

最新站长工具箱源码&#xff0c;拥有几百个功能&#xff0c;安装教程 在 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. 字母收集 思路&#xff1a; 1、预处理 对输入的字符矩阵我们按照要求将其转换为数字分数&#xff0c;由于只能往下和往右走&#xff0c;因此走到&#xff08;i&#xff0c;j&#xff09;的位置要就是从&#xff08;i - 1&#xff0c; j&#xff09;往下走&#…...

计算巨头 Azure、AWS 和 GCP 的比较

云计算领域由三大主要参与者主导&#xff1a;Microsoft Azure、Amazon Web Services (AWS) 和 Google Cloud Platform (GCP)。每个平台都为希望利用云提供基础设施、平台服务等的企业提供强大的功能。在本文中&#xff0c;我们将深入探讨这些平台之间的差异&#xff0c;重点关注…...

Thinkphp5跨域问题常见的处理方法

在ThinkPHP5中&#xff0c;处理跨域问题通常涉及配置中间件或直接在控制器中设置响应头。以下是几种常见的解决跨域问题的方法&#xff1a; 1. 使用中间件处理跨域 你可以创建一个中间件来专门处理跨域请求。这个中间件会检查请求的来源&#xff0c;并设置相应的响应头来允许…...

Matlab编程资源库(9)数据插值与曲线拟合

一、一维数据插值 在MATLAB中&#xff0c;实现这些插值的函数是interp1&#xff0c;其调用格式为&#xff1a; Y1interp1(X,Y,X1,method) 函数根据X,Y的值&#xff0c;计算函数在X1处的值。X,Y是两个等长的已知向量&#xff0c;分别描述采样点和样本值&#xff0c;X1是一个向量…...

matplotlib的科研绘图辅助

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

C++内存管理(候捷)第五讲 笔记

GNU C对allocators的描述 new_allocator 和malloc_allocator&#xff0c;它们都没有特别的动作&#xff0c;无非底部调用operator new和malloc。它们没有用内存池 区别&#xff1a;::operator new是可重载的 智能型的allocator&#xff0c;使用内存池&#xff0c;分一大块然后…...

谷粒商城实战笔记-63-商品服务-API-品牌管理-OSS获取服务端签名

文章目录 一&#xff0c;创建第三方服务模块thrid-party1&#xff0c;创建一个名为gulimall-third-party的模块2&#xff0c;nacos上创建third-party命名空间&#xff0c;用来管理这个服务的所有配置3&#xff0c;配置pom文件4&#xff0c;配置文件5&#xff0c;单元测试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模型&#xff0c;当进行IO操作时&#xff0c;线程会被阻塞&#xff0c;直到操作完成。 比如read和write&#xff0c;通常IO…...

昇思25天学习打卡营第11天|xiaoyushao

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

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

Appium+python自动化(十六)- ADB命令

简介 Android 调试桥(adb)是多种用途的工具&#xff0c;该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具&#xff0c;其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利&#xff0c;如安装和调试…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...