skip to content

What is FilterChainProxy in Spring Security, and what is its job?

level: juniorimportance: must knowfreq 60%

answer

  1. one servlet filter to rule them all
  2. springSecurityFilterChain bean via DelegatingFilterProxy
  3. holds List<SecurityFilterChain>
  4. first matching chain wins
  5. dispatcher, not a security filter itself

basics

~10 s

FilterChainProxy is the single servlet filter Spring Security registers. For each request it picks the first matching SecurityFilterChain and runs that chain's security filters in order.

solid answer

~30 s

FilterChainProxy is the one servlet Filter that Spring Security inserts into the servlet container's filter pipeline (bean name springSecurityFilterChain, reached via DelegatingFilterProxy). It does not do security itself; it holds an ordered List<SecurityFilterChain>, and on every request it walks that list, asks each chain matches(request), and delegates to the first one that matches. That chain's filters (e.g. authentication, CSRF, authorization) then execute in order. This design means all Spring Security's per-request logic funnels through a single entry point, which centralizes ordering, matching, and firewall/HttpFirewall enforcement, instead of scattering many filters directly in web.xml or the container config.

code

java · 14 lines
java
// FilterChainProxy is created for you; conceptually it does:
// for (SecurityFilterChain chain : chains) {
//     if (chain.matches(request)) {
//         return chain.getFilters(); // run these, then continue original chain
//     }
// }

// You normally never build it directly. You declare SecurityFilterChain beans:
@Bean
SecurityFilterChain appChain(HttpSecurity http) throws Exception {
    http.authorizeHttpRequests(a -> a.anyRequest().authenticated())
        .formLogin(Customizer.withDefaults());
    return http.build(); // returns a SecurityFilterChain that FilterChainProxy holds
}

go deeper

for a junior

Know it's the single security filter entry point that picks a chain and runs its filters.

for a middle

Explain the DelegatingFilterProxy bridge and the List<SecurityFilterChain> + first-match dispatch.

for a senior

Discuss HttpFirewall enforcement and why one entry point centralizes ordering/matching.

for a principal

Tie it to multi-chain architectures (API vs UI) and the operational consequences of the single dispatcher.

## The big picture A servlet container (Tomcat, Jetty) runs each request through a chain of `jakarta.servlet.Filter` objects before it reaches your controller/servlet. Spring Security needs to run its own filters (for authentication, CSRF, authorization, etc.), but instead of registering dozens of individual filters with the container, it registers exactly **one**: `FilterChainProxy`. ### How it gets into the container - Spring exposes a bean named `springSecurityFilterChain` (this bean is a `FilterChainProxy`). - A `DelegatingFilterProxy` is registered with the servlet container. `DelegatingFilterProxy` is a thin bridge: the container knows about it, and it looks up the `springSecurityFilterChain` bean from the Spring `ApplicationContext` and delegates every request to it. This lets the actual security filter be a fully Spring-managed bean (with dependency injection) even though the container instantiates filters itself. ### What FilterChainProxy holds `FilterChainProxy` contains an **ordered `List<SecurityFilterChain>`**. A `SecurityFilterChain` is a simple interface with two methods: ```java boolean matches(HttpServletRequest request); List<Filter> getFilters(); ``` - `matches(...)` uses a `RequestMatcher` to decide whether this chain applies to the current request. - `getFilters()` returns the ordered list of security filters for that chain. ### Per-request behavior For each incoming request, `FilterChainProxy`: 1. Applies the `HttpFirewall` (rejects malformed/dangerous requests early). 2. Iterates its `List<SecurityFilterChain>` in order and calls `matches(request)` on each. 3. Selects the **first** chain whose `matches` returns true — **only one chain ever handles a request**. 4. Runs that chain's filters in order (via an internal `VirtualFilterChain`), then hands control back to the container's original filter chain so the request reaches the controller. ### Why this design - Single, well-defined entry point for all security logic. - Central place to enforce ordering and the request firewall. - Multiple independent `SecurityFilterChain`s can coexist (e.g. one for `/api/**` stateless JWT, one for the browser UI with sessions and CSRF). ### Gotchas - FilterChainProxy is **not** the same as an individual filter like `UsernamePasswordAuthenticationFilter` — it is the container/dispatcher of chains. - If no chain matches a request, no security filters run for it (the request just continues down the container's filter chain). In practice you almost always have a catch-all chain so this doesn't accidentally happen.

  • What is DelegatingFilterProxy and why is it needed?
    It's a container-registered filter that delegates each request to a Spring-managed bean (the springSecurityFilterChain / FilterChainProxy). It bridges the servlet container, which instantiates filters itself, to the Spring ApplicationContext so the real filter can be a DI-wired bean.
  • Does FilterChainProxy itself authenticate or authorize requests?
    No. It only selects the matching SecurityFilterChain and invokes that chain's filters. The actual authentication/authorization work is done by individual filters inside the chain (e.g. AuthorizationFilter, UsernamePasswordAuthenticationFilter).

saying these in an interview costs you the question

  • Claiming Spring Security registers many separate filters directly with the container (it registers one FilterChainProxy).
  • Confusing FilterChainProxy with a single security filter like UsernamePasswordAuthenticationFilter.
  • Saying all SecurityFilterChains run for every request (only the first matching one runs).

context