当前位置: 首页 > 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;然后使用该模型来初始化网络的权重参数或作为固定特征提…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观&#xff0c;可持续性好高效率高复用&#xff0c;可移植性好高内聚&#xff0c;低耦合没有冗余规范性&#xff0c;代码有规可循&#xff0c;可以看出自己当时的思考过程特殊排版&#xff0c;特殊语法&#xff0c;特殊指令&#xff0c;必须…...