skip to content

DelegatingFilterProxy

DelegatingFilterProxy is a container-registered filter that delegates to a Spring-managed bean, letting security filters be ordinary beans with dependencies. It explains how a servlet filter can be wired by the ApplicationContext at all.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is DelegatingFilterProxy and why does Spring Security need it?

level: juniorimportance: must knowfreq 70%

answer

  1. container Filter that holds no logic
  2. looks up Spring bean by name, delegates doFilter
  3. delegate = springSecurityFilterChain (FilterChainProxy)
  4. lazy lookup -> defers to ApplicationContext readiness
  5. bridge container lifecycle <-> Spring beans

basics

~20 s

DelegatingFilterProxy is a servlet Filter registered with the container that forwards requests to a Spring-managed filter bean (the security filter chain). It lets Spring beans act as filters even though the container created the proxy.

solid answer

~40 s

DelegatingFilterProxy is a standard jakarta.servlet.Filter that the servlet container registers and manages, but it does no filtering itself. On each request it looks up a Spring bean by name from the WebApplicationContext and delegates doFilter to it. Spring Security registers one named springSecurityFilterChain (a FilterChainProxy). This bridges two worlds: the container owns the filter lifecycle and knows about Filters at startup, while Spring Security's real logic lives in beans created and wired by the ApplicationContext. Without the proxy, the container would need to instantiate the security filter directly, losing dependency injection, AOP, and Spring lifecycle. It also defers bean lookup until the first request (or context readiness), so the Spring context can finish initializing before the filter is used.

go deeper

for a junior

Know it's a servlet filter that forwards to a Spring bean, and the bean is the security filter chain.

for a middle

Explain the name wiring (springSecurityFilterChain / FilterChainProxy) and that Boot auto-registers it.

for a senior

Articulate the two ownership models (container vs ApplicationContext) and why bridging is necessary for DI/AOP/lifecycle.

for a principal

Discuss deferred initialization, root-vs-child context lookup, targetFilterLifecycle, and the full delegation chain including FilterChainProxy selection.

## The problem it solves A servlet container (Tomcat, Jetty, etc.) manages the lifecycle of `jakarta.servlet.Filter` instances: it instantiates them, calls `init()`, `doFilter()`, and `destroy()`. Filters are typically declared in `web.xml` or via `ServletContext` registration at startup. But Spring Security's real filtering logic lives in **Spring beans** — objects created, dependency-injected, and lifecycle-managed by the Spring `ApplicationContext`, not by the container. These two ownership models don't naturally meet: the container doesn't know about Spring beans, and Spring beans aren't containers filters. ## What DelegatingFilterProxy is `org.springframework.web.filter.DelegatingFilterProxy` is itself a real `Filter` that the container registers and manages. But it contains **no security logic**. Its only job is to look up a Spring bean (by name) from the Spring `WebApplicationContext` and delegate `doFilter(...)` calls to that bean. So the container manages a lightweight proxy, and the proxy forwards to a fully Spring-managed delegate. ## How the name wiring works - The proxy has a **target bean name**. By default it's the filter's registered name; you can override it via the `targetBeanName` init-param. - Spring Security registers the proxy under the name **`springSecurityFilterChain`**, and the delegate bean is also named **`springSecurityFilterChain`** — an instance of `org.springframework.security.web.FilterChainProxy`. - In classic setups, `AbstractSecurityWebApplicationInitializer` (or `web.xml`) registers the `DelegatingFilterProxy` named `springSecurityFilterChain`, mapped to `/*`. - In Spring Boot, `SecurityFilterAutoConfiguration` registers a `DelegatingFilterProxyRegistrationBean` that wires the proxy to the `springSecurityFilterChain` bean automatically — you never write this by hand. ## Deferred initialization — the key mechanism At container startup the target Spring bean may not exist yet (the `ApplicationContext` may still be initializing). `DelegatingFilterProxy` therefore **lazily looks up the delegate on the first request** rather than in `init()`. It finds the `WebApplicationContext` (by default via `WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext)`, i.e., the root context), fetches the bean, and caches it. This deferral is why the proxy exists at all: it lets the servlet filter chain be assembled at startup while the actual security beans come online later, driven by the Spring context lifecycle. ## Delegate lifecycle By default the proxy does **not** invoke `init()`/`destroy()` on the delegate — Spring manages the bean's lifecycle. You can opt into invoking the servlet `Filter.init/destroy` on the delegate via the `targetFilterLifecycle` init-param (default `false`). ## Which context does it search? By default the **root** `WebApplicationContext` (the one created by `ContextLoaderListener`). You can point it at a specific context with the `contextAttribute` init-param. In Boot there is a single context, so this rarely matters. ## The full chain of delegation `Container filter chain` -> `DelegatingFilterProxy` -> `FilterChainProxy` (the `springSecurityFilterChain` bean) -> matched `SecurityFilterChain` -> ordered list of security filters (e.g., `SecurityContextHolderFilter`, `CsrfFilter`, `UsernamePasswordAuthenticationFilter`, `AuthorizationFilter`). Note the two-level indirection: the proxy bridges container->Spring, and `FilterChainProxy` then selects among possibly multiple `SecurityFilterChain`s by request matcher. ## Gotchas - Confusing `DelegatingFilterProxy` (the bridge) with `FilterChainProxy` (the actual dispatcher). Only the latter contains security filters. - Bean-name mismatch: if the `targetBeanName` doesn't resolve to a bean, you get a `NoSuchBeanDefinitionException` on first request. - Registering the proxy with the wrong URL mapping (must cover all secured paths, typically `/*`). - In multi-context apps, expecting the delegate in the child (DispatcherServlet) context when it lives in the root context. ## When you touch it Almost never directly in Boot. You encounter it when: reading stack traces, doing pure servlet/`web.xml` setups, adding custom filters that must be Spring beans, or debugging why a filter isn't being invoked.

  • What is the actual bean the proxy delegates to in Spring Security?
    A FilterChainProxy registered as the bean springSecurityFilterChain, which then dispatches to one of the SecurityFilterChain instances based on request matching.
  • In a Spring Boot app, who registers the DelegatingFilterProxy?
    SecurityFilterAutoConfiguration registers a DelegatingFilterProxyRegistrationBean that wires the proxy to the springSecurityFilterChain bean; you don't write it yourself.

saying these in an interview costs you the question

  • Saying DelegatingFilterProxy contains the security filters
  • Thinking it does the authentication/authorization itself
  • Believing the servlet container instantiates the security beans directly

context

open as a page

Explain the difference between DelegatingFilterProxy and FilterChainProxy.

level: middleimportance: must knowfreq 60%

basics

~10 s

DelegatingFilterProxy is the container-registered bridge that forwards to a Spring bean. FilterChainProxy is that bean — the Spring-managed filter that holds the security filter chains and runs the ordered security filters.

open as a page

How does the DelegatingFilterProxy get registered in a Spring Boot application, and how would you do it without Boot?

level: middleimportance: should knowfreq 45%

basics

~10 s

In Boot, SecurityFilterAutoConfiguration registers a DelegatingFilterProxyRegistrationBean pointing at the springSecurityFilterChain bean. Without Boot you register it via web.xml or AbstractSecurityWebApplicationInitializer with the same bean name and a /* mapping.

open as a page

Explain the deferred initialization of DelegatingFilterProxy and which ApplicationContext it resolves its delegate from. What can go wrong?

level: seniorimportance: should knowfreq 35%

basics

~10 s

The proxy is created by the container at startup but doesn't fetch its delegate bean until the first request, giving the Spring context time to initialize. By default it looks in the root WebApplicationContext.

open as a page

You need a stateful, dependency-injected custom servlet filter that runs across the whole app. How does DelegatingFilterProxy help, and what design trade-offs apply?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

Register a DelegatingFilterProxy pointing at your Spring-managed filter bean. The container manages the proxy while Spring injects and lifecycle-manages your real filter, so it gets dependencies and AOP even though the container owns filter registration.

open as a page