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

工程师创意竞赛全流程策划:从社区激活到公平投票的实战指南

1. 项目概述&#xff1a;一场别开生面的工程师创意竞赛又到了二月底&#xff0c;这意味着我们年初启动的那个“独轮车”图片配文竞赛&#xff0c;终于要进入最激动人心的投票环节了。我记得很清楚&#xff0c;那是2012年2月初&#xff0c;编辑部觉得冬天太沉闷&#xff0c;想找…...

构建本地化X内容智能引擎:从数据捕获到AI辅助创作的全流程实践

1. 项目概述&#xff1a;打造你的本地X内容智能引擎 如果你和我一样&#xff0c;每天花大量时间在X&#xff08;原Twitter&#xff09;上&#xff0c;不是为了刷屏&#xff0c;而是为了工作——寻找灵感、分析趋势、构思内容&#xff0c;那你一定体会过那种“信息过载”与“灵…...

9.实战案例拆解

好的,我们开始。先别急着看那些“月入十万”的爽文,我这边先给你看一段我昨晚在调试一个树莓派Pico W的I2C总线时,在终端里敲出来的报错信息: [ERROR] I2C timeout: SDA line held low by device at 0x3C这条错误让我折腾了半小时。最后发现是传感器模块的电源纹波太大,导…...

Hummingbot自动化交易框架:从原理到实战的量化交易指南

1. 项目概述&#xff1a;一个为专业交易者打造的自动化交易框架如果你在加密货币交易领域摸爬滚打过一段时间&#xff0c;一定会对“手动盯盘”的疲惫和“情绪化操作”的代价深有体会。市场24/7运转&#xff0c;机会转瞬即逝&#xff0c;而人的精力终究有限。这正是我最初接触并…...

SAP ABAP开发避坑指南:NATIVE SQL里那个冒号和MANDT字段,你写对了吗?

SAP ABAP开发实战&#xff1a;NATIVE SQL高频陷阱与性能优化全解析 在SAP ABAP开发领域&#xff0c;NATIVE SQL就像一把双刃剑——它既能突破Open SQL的限制直接操作底层数据库&#xff0c;又隐藏着无数让开发者"踩坑"的语法细节。根据SAP官方统计&#xff0c;超过60…...

VMware Workstation Pro 17免费许可证密钥终极指南:快速激活专业虚拟化工具

VMware Workstation Pro 17免费许可证密钥终极指南&#xff1a;快速激活专业虚拟化工具 【免费下载链接】VMware-Workstation-Pro-17-Licence-Keys Free VMware Workstation Pro 17 full license keys. Weve meticulously organized thousands of keys, catering to all major …...

3个步骤搭建Sunshine游戏串流服务器:从零到一的完整指南

3个步骤搭建Sunshine游戏串流服务器&#xff1a;从零到一的完整指南 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾经梦想过在客厅的电视上玩书房电脑里的3A大作&#xf…...

VMware Unlocker 3.0:5分钟快速配置macOS虚拟机终极指南

VMware Unlocker 3.0&#xff1a;5分钟快速配置macOS虚拟机终极指南 【免费下载链接】unlocker VMware Workstation macOS 项目地址: https://gitcode.com/gh_mirrors/unloc/unlocker VMware Unlocker 3.0是一款专为破解VMware限制而设计的开源工具&#xff0c;让您能在…...

从批判到机遇:技术人的思维重塑与硬科技创新实践

1. 从“批判”到“机遇”&#xff1a;一位科技编辑的思维重塑之旅最近和几位在芯片设计公司工作的老朋友聊天&#xff0c;话题总是不自觉地绕回到行业现状上&#xff1a;摩尔定律逼近物理极限&#xff0c;研发成本指数级攀升&#xff0c;全球供应链的波动……大家言语间多少带着…...

基于Python与yfinance构建本地化股票量化筛选器:以PKScreener为例

1. 项目概述与核心价值 最近在和一些做量化交易的朋友交流时&#xff0c;发现大家普遍面临一个痛点&#xff1a;虽然市面上有各种股票数据接口和量化平台&#xff0c;但真正能快速、灵活地根据自定义条件进行股票筛选&#xff0c;并且能本地化部署、深度定制的工具却不多。要么…...