恶意不息免安装绿色中文版
42.6G · 2025-11-05
属于 Spring Web(Servlet 规范 + Spring Framework) 的类,不是 Spring Security 专属, 它是连接 Servlet 容器中的 Filter 与 Spring 容器中的 Bean 的关键桥梁。
它本身是一个标准的 jakarta.servlet.Filter,但是并不直接做实际的过滤逻辑,而是 把请求委托给 Spring 容器里定义的某个 Bean(通常是一个 Filter 类型的 Bean) 去执行(如 FilterChainProxy)去执行。
web.xml(或 ServletContext 注册的 Filter),只能直接加载类实例,无法感知 Spring 容器里的 Bean。DelegatingFilterProxy 作为适配器,把 Servlet 容器里的 Filter 请求转发给 Spring 容器里的目标 Bean。简单说:
Tomcat → 调用 DelegatingFilterProxy → 找到 Spring 容器中的 bean → 委托执行。
Servlet 容器启动时,DelegatingFilterProxy 被注册为 Filter。
它会从 Spring 容器里找到与自己名字(或配置的名字)相同的 Bean(通常是 FilterChainProxy)。
每次请求进来时:
DelegatingFilterProxy#doFilter(...) 会调用目标 Bean 的 doFilter(...)。public class DelegatingFilterProxy extends GenericFilterBean {
private String targetBeanName;
private WebApplicationContext webApplicationContext;
private volatile Filter delegate;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 初始化目标 Bean(只做一次)initFilterBean -> this.delegate = this.initDelegate(wac);
Filter delegateToUse = this.delegate;
// 委托目标 Bean 执行过滤逻辑
delegateToUse.doFilter(request, response, filterChain);
}
}
角色:Spring Security 的核心入口 Filter。
职责:
DelegatingFilterProxy 转发)。DelegatingFilterProxy。Filter delegate = getDelegate(); // 获取 springSecurityFilterChain Bean
delegate.doFilter(request, response, filterChain);
delegate 就是 FilterChainProxy 实例。
所以 FilterChainProxy#doFilter() 被 Servlet 容器调用,传入原始 FilterChain(继续调用 DispatcherServlet 或下一个 Filter)。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse) response);
// 找到匹配的 SecurityFilterChain
List<Filter> filters = null;
// 多条 SecurityFilterChain 如何匹配
for (SecurityFilterChain chain : this.filterChains) {
if (chain.matches(request)) {
// 默认只执行第一个匹配的; 所以在配置多个链时,顺序很重要,URL 模式越具体的链应该放前面。
filters = chain.getFilters();
break;
}
}
// 没匹配到 -> 直接放行
if (filters == null || filters.size() == 0) {
this.filterChainDecorator.decorate(chain).doFilter(firewallRequest, firewallResponse);
return;
}
// 如果匹配:
// 创建“重置链”,用于恢复请求状态并调用原始 FilterChain
FilterChain reset = (req, res) -> {
// 恢复请求状态,清理 Security Filter 改动。
firewallRequest.reset();
chain.doFilter(req, res); // 调用原始 FilterChain, 其实就是 Servlet 容器原本的 FilterChain(最终会到 DispatcherServlet)。
};
// 创建 VirtualFilterChain,执行 Filters, 最后调用 reset
this.filterChainDecorator.decorate(reset, filters).doFilter(firewallRequest, firewallResponse);
}
SecurityFilterChain 是一个接口,包含一组 Spring Security 的内置 Filter 和 对应一个 URL 配置模式。public interface SecurityFilterChain {
boolean matches(HttpServletRequest request);
List<Filter> getFilters();
}
RequestMatcher 判断请求是否匹配, 找到第一个匹配的链执行。
matches() 通常是 DefaultSecurityFilterChain 实现,内部使用 RequestMatcher 判断 URL 是否匹配:public boolean matches(HttpServletRequest request) {
return this.requestMatcher.matches(request);
}
可以有多个 SecurityFilterChain(多安全配置),比如:
/api/** → JWT 认证的过滤器链/admin/** → Session 登录的过滤器链private static class VirtualFilterChain implements FilterChain {
private final FilterChain originalChain;// FilterChain resert
private final List<Filter> additionalFilters; // 这一条 SecurityFilterChain 内的所有 Security Filter
private final int size; // Filter 数量
private int currentPosition = 0; // 当前执行到第几个 Filter
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
// 递归终止条件:如果已经执行完 additionalFilters 中的所有 Filter,调用 原始 FilterChain
// 保证请求最终能到 DispatcherServlet 或原始 Filter 链。
if (currentPosition == additionalFilters.size()) {
// 所有 Security Filter 执行完后 -> 继续执行原始 FilterChain,保证请求最终能到达 DispatcherServlet。
originalChain.doFilter(request, response);
return;
}
this.currentPosition++;
// 取出当前 Filter
Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
// 调用它的 doFilter, 把 VirtualFilterChain 自身 (this) 作为下一个 FilterChain 传入
nextFilter.doFilter(request, response, this); // 递归
}
}
顺序执行
additionalFilters 列表的顺序。AuthenticationException),会被 ExceptionTranslationFilter 捕获处理,不会继续执行后续 Filter。递归链
chain.doFilter(),进入下一层 Filter。最终回原始链
currentPosition == size,执行 originalChain.doFilter(),把请求交回原始的 Servlet FilterChain(进入 DispatcherServlet)。springSecurityFilterChain 的 Bean(即 FilterChainProxy)。FilterChainProxy 注册为一个 名为 "springSecurityFilterChain" 的 Bean。@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// HttpSecurity DSL 配置生成 SecurityFilterChain
return http.build();
}
}
底层过程:
@EnableWebSecurity 会触发 WebSecurityConfiguration 自动配置,注册 springSecurityFilterChain BeanFilterChainProxy@Bean(name = "springSecurityFilterChain")
public FilterChainProxy springSecurityFilterChain(List<SecurityFilterChain> chains) {
return new FilterChainProxy(chains);
}
假设你在 web.xml 或 Spring Boot 默认注册了(一般就自动配置):
<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>
Tomcat / Servlet 容器启动:
DelegatingFilterProxyDelegatingFilterProxy.init()@Override
public void init(FilterConfig filterConfig) {
// 1. Bean 名称,默认为 filter-name
String targetBeanName = getTargetBeanName();
// 2. 从 Spring WebApplicationContext 获取 Bean
this.delegate = obtainWebApplicationContext(filterConfig)
.getBean(targetBeanName, Filter.class);
// delegate 就是 FilterChainProxy 实例
}
delegate 就是 FilterChainProxy Bean@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws ServletException, IOException {
this.delegate.doFilter(request, response, chain); // ✅ 这里调用 FilterChainProxy.doFilter()
}
┌───────────────────────────────┐
│ 客户端请求 │
└───────────────┬───────────────┘
│
▼
Tomcat / Servlet 容器 Filter 链
│
▼
┌───────────────────────────────┐
│ DelegatingFilterProxy (Filter) │
│ init(): 获取 delegate Bean │
│ delegate = springSecurityFilterChain (FilterChainProxy) │
└───────────────┬───────────────┘
│ doFilter(request, response, chain)
▼
┌─────────────────────────┐
│ FilterChainProxy │
│ doFilterInternal(): │
│ 1️⃣ Firewall 防护 │
│ 2️⃣ 匹配 SecurityFilterChain │
│ 3️⃣ 创建 VirtualFilterChain │
│ 4️⃣ 执行 Security Filter 链 │
└───────────────┬─────────┘
│
▼
┌─────────────────────────┐
│ VirtualFilterChain │
│(递归执行每个 Filter) │
│ ┌───────────────┐ │
│ │ SecurityFilter1│ --> chain.doFilter(this)
│ ├───────────────┤
│ │ SecurityFilter2│ --> chain.doFilter(this)
│ └───────────────┘
│
│ 当 currentPosition == size
│ 执行 reset 链
▼
┌───────────────────────────────┐
│ FilterChain reset (lambda) │
│ firewallRequest.reset() │
│ originalChain.doFilter() │ <-- 调用原始 FilterChain
└───────────────┬───────────────┘
│
▼
┌──────────────────────────┐
│ DispatcherServlet / MVC │
│ Controller 业务处理 │
└──────────────────────────┘
reset 链
reset 链就是保证 请求能回到原始处理链SecurityFilterChain
original FilterChain / DispatcherServlet
42.6G · 2025-11-05
37.9G · 2025-11-05
33.7G · 2025-11-05