Skip to main content

Command Palette

Search for a command to run...

Key Elements of Spring Security Architecture Explained

A comprehensive guide to decode each component of the Architecture

Updated
6 min read
Key Elements of Spring Security Architecture Explained
R

Java Dev based in India. My playground? Web services, RESTful APIs, Distributed Systems, and Open Source Developer Tooling.

This article focuses on an in-depth architectural overview of Spring Security. I can confidently say that this is one of the best breakdowns you have ever encountered on Spring Security, but there are some prerequisites that you should have before moving forward. They are:

Pre-requisites:
1. Understanding of Servlets
2. What is a Request and Response
3. Understanding of MVC Architecture
4. What is a Front Controller

Assuming you've got the foundational blocks in place, we're about to unwrap the intricate architecture of Spring Security.

The General Assumption

When discussing the life cycle of a request, it's easy to assume a straightforward process: a client sends a request, the server processes it, and the application responds with the requested data. However, this oversimplification misses several critical steps.

In reality, application servers, particularly those with Servlet containers, introduce additional layers of complexity and security. When a request reaches the server, it first encounters the Servlet container, which manages the servlets. But here's the thing—the servlet container doesn't just accept any request directly. Before a request can reach the servlet, it undergoes a rigorous process of validation and authentication.

This process is known as the Servlet Request Processing Pipeline, which includes a Filter Chain—a series of filters that validate the incoming request from the client. Every request must successfully pass through these filters before being granted access to the application.

Now that we’ve set the stage, let’s have a detailed breakdown on what these filters are and how Spring leverages them to authenticate and secure incoming requests.

The Breakdown 💥

1. Servlet Filter Chain

  • The FilterChain is a component of the servlet container that plays a fundamental role in the Standard Servlet Request Processing Pipeline. The FilterChain contains a list of Filter objects in a proper sequential order.

  • Each filter in the filter chain performs a validation or customization logic on the incoming requests. This helps in assuring the authenticity of the incoming requests. e.g.,

    • Validation Filters: Verifying request content type, method type, authentication, authorization, parameters, etc.

    • Logging filters: for tracking request details.

    • Encryption filters: for secure data transmission.

    • Authentication filters: for user login and access control (usually added on the server side).

  • Any request that comes from the client passes through the FilterChain of the Servlet Container. Once the request passes through all the Filters, it proceeds to the Front Controller/DispatcherServlet. The DispatcherServlet then takes charge of routing the request to the appropriate resource for further handling and response generation.

Spring Here leverages the opportunity of validating the requests even before they reach the application through filters by introducing its own Filter Delegation Filter Proxy to the Servlet Filter Chain.

2. DelegationFilterProxy

  • DelegationFilterProxy is the Spring-Managed custom filter, it helps in delegating the request filtering process to a spring bean responsible for managing the Security Filtration process.

  • This step is crucial in a Spring Security-driven application. Since the servlet container doesn't understand Spring Beans and their configuration, the DelegationFilterProxy helps delegate control to the Spring Bean.

  • The spring bean here is a FilterChainProxy.

3. Filter Chain Proxy

  • The FilterChainProxy is responsible for managing a list of SecurityFilterChain beans.

  • Each SecurityFilterChain is a chain of security filters that are designed to authenticate the request with different approaches.

    • E.g.,

      1. We can have SecurityFilterChain 1 authenticating requests based on the entered username and password.

      2. Also, we can have SecurityFilterChain 2 authenticating the request based on the API Key. Additionally, we can have as many as we require to complete all the authentication flows.

  • When the FilterChainProxy after gaining control over the incoming request, it validates if the request path is against the allowed patterns in the SecurityFilterChains, Each SecurityFilterChain will have a URI Pattern assigned to which they have to be invoked.

  • If the incoming request URI pattern matches with any of the SecurityFilterChains Patterns, the request is passed through the respective SecurityFilterChain.

4. Security Filter Chain

  • The SecurityFilterChain contains a list of Security Filters (Objects) each tailored to specific security requirements.

  • The request passes through all the security filters serially, if any filter fails to authenticate the request, an Unauthorized or Forbidden response is returned to the client.

  • If the request successfully passes through the filters, the request is then allowed to access the application resources.

5. UsernamePasswordAuthenticationFilter

  • UsernamePasswordAuthenticationFilter is one of the important filters used to authenticate incoming requests. UsernamePasswordAuthenticationFilter is mainly utilized during Login Operations. For any request to pass through the filter successfully, the client must either be already logged in or the request should be for a new login attempt.

  • If the client is already logged in, the filter bypasses the authentication process.

  • If the client is not logged in and the request does not contain a Username and Password, the request is rejected, and the user receives an Unauthorized response.

  • If the request is made to log in with a Username and Password, the filter attempts to authenticate and returns a corresponding success or failure response.

6. SecurityContext

  • The SecurityContext holds the security-related information for the current thread, which includes authenticated principals and granted authorities.

  • This SecurityContext is then placed in a container called SecurityContextHolder, through which the authentication details are accessed throughout the application. This ensures that the authenticated user information is available during the request-response lifecycle.

  • The SecurityContextHolder is always cleared after the response is committed back to the client. However, it should be updated with the SecurityContext during every subsequent request. To ensure longer persistence or login information, the SecurityContext is also stored in the HttpSession.

7. HttpSession

  • HttpSession is used to maintain user session information between multiple requests. It stores the authenticated principal and other relevant session data.

  • In Spring Security, upon successful authentication, the SecurityContext is stored in the session to preserve user information and avoid re-authentication for every request.

  • You can read more about the HttpSession and Authentication Flow in this article here 👉 Click here to read about HttpSession

8. SecurityContextPersistanceFilter

  • The SecurityContextPersistenceFilter is responsible for managing the SecurityContext across multiple requests. It loads the SecurityContext from the HttpSession into the SecurityContextHolder at the beginning of each request.

  • After the request is processed through the security filters in the chain, the SecurityContextPersistenceFilter stores the updated SecurityContext back into the session to ensure the user remains authenticated across different requests.

Conclusion:

This article has provided a comprehensive breakdown of Spring Security’s architecture, delving into its core modules—from the Servlet Filter Chain and DelegationFilterProxy to the SecurityContext and SecurityContextPersistenceFilter. These insights aim to equip developers with a solid understanding of how Spring Security manages authentication.

Stay tuned for our next article, where we explore in detail Authentication flows, and the practical implementation of database-based authentication. Your thoughts and questions are always welcome! Please do like and share!