Spring Security and the Chain of Responsibility Design Pattern

From parent article

Chain of Responsibility Design Pattern

The Chain of Responsibility design pattern is a behavioural pattern that allows the client to pass a request along a chain of potential handlers until one of the them handles the request.

In terms of terminology the following are analogous.

Advantages

  1. Modularity & Reusability: Each security concern is encapsulated in its own filter, making the system modular, easier to manager, and reusable across different applications.
  2. Flexibility & Order of Execution: Filters can be easily added, removed, or reordered. This pattern enforces a well-defined order of execution for security checks, ensuring each step is performed in the correct sequence.
  3. Separation of Concerns: Each filter has a single responsibility, which simplifies maintenance and testing.
  4. Short-Circuiting: If a handler throws an exception, the chain will “fail fast,” returning an error to the user and preventing further processing, thereby protecting the application from harmful exploits.

Components:

  1. Handler: An interface or abstract class that defines a method to handle the request and a reference to the next handler in the chain.
  2. Concrete Handlers: Classes that implement the handler interface and decides whether to process or pass it to the next handler in the chain.
  3. Client: the object that initiates the request.

Chain Setup

When the client sends a request to the chain, each handler in the chain has two options:

  1. Process the Request: The handler may choose to process the request by invoking its handle method. This method determines whether to:

  • - Reject the Request: If the handler finds the request invalid or unsafe, the chain is short-circuited, meaning the process stops, and an error is sent back to the client.
  • - Continue Processing: If the handler processes the request and finds it valid, it can pass the request to the next handler in the chain.

2. Pass the Request: The handler may also decide not to process the request itself and instead pass it directly to the next handler in the chain without invoking the handle method.

Below is an architectural diagram of the Chain of Responsibility, where the dotted lines indicate the possible paths that the request might follow.

Example of a request that got rejected By Handler 2.

Example of a request that got handled by all handlers and is resolved

Spring Security's architecture is built on top of the Spring Servlet Architecture .

Spring Servlet Architecture

When a client sends a request to our web application,

  1. It first passes through a chain of filters that preprocess the request.
  2. After passing through these filters, the request reaches the DispatcherServlet.
  3. The DispatcherServlet will dispatch the request to the correct Controller.
  4. The Controller then dispatches the request to the appropriate controller. The controller processes the request and generates a response.

Filters in the chain can decide whether to

  1. process the request
  2. pass it to the next filter
  3. or block it.

If a filter processes the request and encounters an exception, the request does not get passed to the next filter; instead, an error response is sent back to the client.

Spring Security Filter Chain

Spring Security integrates with the Spring Servlet Architecture by introducing a dedicated security filter chain alongside the existing servlet filter chain. This security filter chain is responsible for handling authentication, authorization, and other security checks before the request reaches the business logic of the application (i.e., the controller).

The advantage of this architecture is that it is highly composable and configurable. We can easily add, remove, modify, reorder security filters, and even swap out entire Security Filter Chainsas needed.

Choosing Security Filter Chain

The FilterChainProxy manages a list of Security Filter Chain instances. When an incoming request is received, the matches method in the SecurityFilterChain interface determines which Security Filter Chain instance should handle the request.

Adding Security Filter to the Chain

Let’s add the UsernamePasswordAuthenticationFilter filter after Security Filter 2 and before Security Filter N.

Removing Security Filter from the Chain

Lets remove Security Filter 2 from the Chain.


要查看或添加评论,请登录

社区洞察

其他会员也浏览了