Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 47

Spring Security Filter Chain Explained

Recommended resources

Hello! Welcome to a new module in our course. Having covered testing, we're now shifting our focus to a critical aspect of any production-ready application: security. Over the next series of lessons, we'll explore the powerful Spring Security framework, which provides comprehensive security services for Java applications.

Your background in system design and microservices will be particularly useful here, as security often involves applying architectural patterns to protect resources and data. Today, we'll start with the most fundamental of these patterns.

This lesson addresses the learning outcome: Explain the role of the Spring Security filter chain in securing web requests. We will deconstruct the architecture that allows Spring Security to intercept every incoming HTTP request to your application, forming the foundation for all authentication and authorization logic we'll build later.

1. The Foundation: Servlet Filters

Before we dive into Spring Security itself, we need to understand the technology it's built upon: Servlet Filters. In the Java ecosystem, a web application running in a servlet container (like the embedded Tomcat server in Spring Boot) can define a series of filters.

Think of this as a pipeline or a series of checkpoints. Every single HTTP request that comes into your application must pass through this chain of filters before it reaches your controller (specifically, the DispatcherServlet in Spring MVC).

Each filter in the chain has two primary capabilities:

  1. It can inspect and even modify the incoming request or the outgoing response.
  2. It can decide whether to pass the request along to the next filter in the chain or to halt processing entirely (for example, by returning an "access denied" error).

A filter is an implementation of the jakarta.servlet.Filter interface, which has a crucial method: doFilter(request, response, chain). The magic happens when a filter calls chain.doFilter(request, response). This call passes control to the next filter in the chain. If a filter doesn't make this call, the request processing stops there.

A Review of Filters

The official Spring Security documentation provides a concise review of servlet filters. This will give you the formal definition of the concept we're discussing.

Please read the initial section titled 'A Review of Filters'. Focus on the diagram and the explanation of how a FilterChain works. Notice the chain.doFilter(request, response) call in the code example; this is the key mechanism for passing control.


2. How Spring Security Hooks In

This filter chain is a feature of the servlet container, which exists outside of Spring's ApplicationContext. This presents a challenge: how can Spring manage security using its own beans and dependency injection if the filter chain is managed by the servlet container?

Spring solves this with a clever bridge pattern using two key components:

  1. DelegatingFilterProxy: This is a standard servlet filter that gets registered with the servlet container. However, it doesn't contain any security logic itself. Its only job is to find a specific bean in the Spring ApplicationContext and delegate the request to it.
  2. FilterChainProxy: This is the Spring bean that the DelegatingFilterProxy delegates to. The FilterChainProxy is the main entry point for all of Spring Security. It acts as a master controller, managing one or more dedicated security filter chains.

This architecture effectively bridges the gap, allowing a standard servlet filter to hand off control to the Spring-managed world.

Spring Security FilterChain Architecture
This diagram shows how Spring Security integrates with the servlet `FilterChain`. A request passes through the container's standard filters until it hits the `DelegatingFilterProxy`. This proxy then hands the request over to the `FilterChainProxy` bean within the Spring context, which in turn invokes the specific `SecurityFilterChain` containing all of Spring's security logic.

3. The SecurityFilterChain

The FilterChainProxy's main responsibility is to route the request to the correct SecurityFilterChain.

A SecurityFilterChain is an ordered list of Spring-managed security filters. These are the beans that do the actual work of authentication, authorization, CSRF protection, header writing, and so on.

A key feature of this design is that you can define multiple SecurityFilterChain beans, each responsible for a different URL pattern. This allows for highly granular security rules. For example, requests to /api/** might need JWT authentication, while requests to /admin/** might require a session-based login, and requests to /public/** might not need any security at all. The FilterChainProxy will look at the incoming request and select the first matching SecurityFilterChain to handle it.

Spring Security Multiple Filter Chains Architecture
This diagram illustrates how the `FilterChainProxy` can manage multiple, independent `SecurityFilterChain`s. It matches an incoming request's URL to the configured patterns (e.g., `/api/**`) and dispatches it to the corresponding chain, enabling different security rules for different parts of your application.

This concept of routing requests based on paths to different processing chains is a common pattern in system design, similar to how an API gateway might apply different policies to different downstream services.


4. Viewing the Filter Chain in Action

When you add the Spring Boot Starter for Security, Spring automatically configures a default SecurityFilterChain with a standard set of filters. You can see this list printed in your application logs on startup.

However, to truly understand what's happening, you need to see the chain execute for a live request.

Spring Security Architecture Principles by Daniel Garnier-Moiroux @ Spring I/O 2024

In this talk from Spring I/O, Daniel Garnier-Moiroux, a Spring Security committer, explains the core architectural principles. He provides a fantastic, practical demonstration of the filter chain.

Please watch the following segments: (08:52 - 11:17): The speaker explains what a Filter is, how the chain is invoked (the do filter call stack), and how it relates to your controllers. (18:28 - 20:57): This is the most practical part. The speaker demonstrates how to enable TRACE-level logging for Spring Security to see the entire filter chain being executed for each request. This is an invaluable debugging technique. (20:57 - 21:59): A concise recap of the key points about filters and the security filter chain.

The key takeaway from the video is the "ninja trick" of enabling TRACE logging. By adding logging.level.org.springframework.security=TRACE to your application.properties file, you get a detailed log of every filter that processes your request, in order. This is the single most effective tool for debugging Spring Security issues.


5. A Deeper Architectural Walkthrough

To reinforce these concepts, let's watch another explanation that uses a debugger to step through the code, showing the DelegatingFilterProxy and FilterChainProxy in action.

🔒 Spring Security Architecture: The Bigger Picture Explained! 🚀

The channel CodeSnippet provides a very detailed walkthrough of the Spring Security architecture. We'll focus on the parts that visually demonstrate the filter chain.

Watch the following two clips: (05:37 - 07:49): See what happens when you just add the security dependency. Spring Boot auto-configures a default SecurityFilterChain that secures all endpoints. (07:59 - 12:18): This is a great visualization. It explains the roles of DelegatingFilterProxy and FilterChainProxy and how they connect the servlet world to the Spring world. The demonstration using the debugger to inspect the list of filters inside the FilterChainProxy makes the concept very tangible.

This walkthrough solidifies the connection between the theory and the actual objects running in your application. You can see how the DelegatingFilterProxy acts as the entry point from the outside, leading to the FilterChainProxy which holds the list of actual security filters that will be applied.


Conclusion

In this lesson, we dissected the core architecture of Spring Security. You've learned that it's not magic, but a well-designed system built on standard Java Servlet technology.

Key Takeaways:

  • Spring Security's functionality is delivered via a SecurityFilterChain, which is an ordered list of security filters.
  • It hooks into the standard Java Servlet Filter mechanism using a bridge pattern involving DelegatingFilterProxy and FilterChainProxy.
  • The DelegatingFilterProxy is a servlet filter that acts as the bridge from the servlet container to the Spring context.
  • The FilterChainProxy is a Spring bean that receives the request and routes it to the appropriate SecurityFilterChain based on the request's URL.
  • Each filter in the chain performs a specific security task (e.g., authentication, CSRF protection, authorization).
  • You can inspect the active filter chain by enabling TRACE-level logging for the org.springframework.security package, a crucial debugging technique.

Understanding this filter chain architecture is the key to mastering Spring Security. Every feature we discuss from now on—authentication, authorization, JWT handling—is implemented as one or more filters within this chain.

In our next lesson, we'll start putting this knowledge to use by configuring our first SecurityFilterChain to apply basic authentication and define simple URL-based authorization rules.