# Architecture

This section discusses Spring Security’s high level architecture within Servlet based applications.
We build on this high level understanding within [Authentication](authentication/index.html#servlet-authentication), [Authorization](authorization/index.html#servlet-authorization), [Protection Against Exploits](exploits/index.html#servlet-exploits) sections of the reference.

## A Review of `Filter`s

Spring Security’s Servlet support is based on Servlet `Filter`s, so it is helpful to look at the role of `Filter`s generally first.
The picture below shows the typical layering of the handlers for a single HTTP request.

![filterchain](../_images/servlet/architecture/filterchain.png)

Figure 1. FilterChain

The client sends a request to the application, and the container creates a `FilterChain` which contains the `Filter`s and `Servlet` that should process the `HttpServletRequest` based on the path of the request URI.
In a Spring MVC application the `Servlet` is an instance of [`DispatcherServlet`](https://docs.spring.io/spring-framework/docs/5.3.16/reference/html/web.html#mvc-servlet).
At most one `Servlet` can handle a single `HttpServletRequest` and `HttpServletResponse`.
However, more than one `Filter` can be used to:

* Prevent downstream `Filter`s or the `Servlet` from being invoked.
  In this instance the `Filter` will typically write the `HttpServletResponse`.

* Modify the `HttpServletRequest` or `HttpServletResponse` used by the downstream `Filter`s and `Servlet`

The power of the `Filter` comes from the `FilterChain` that is passed into it.

Example 1. `FilterChain` Usage Example

Java

```
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	// do something before the rest of the application
    chain.doFilter(request, response); // invoke the rest of the application
    // do something after the rest of the application
}
```

Kotlin

```
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
    // do something before the rest of the application
    chain.doFilter(request, response) // invoke the rest of the application
    // do something after the rest of the application
}
```

Since a `Filter` only impacts downstream `Filter`s and the `Servlet`, the order each `Filter` is invoked is extremely important.

## DelegatingFilterProxy

Spring provides a `Filter` implementation named [`DelegatingFilterProxy`](https://docs.spring.io/spring-framework/docs/5.3.16/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html) that allows bridging between the Servlet container’s lifecycle and Spring’s `ApplicationContext`.
The Servlet container allows registering `Filter`s using its own standards, but it is not aware of Spring defined Beans.`DelegatingFilterProxy` can be registered via standard Servlet container mechanisms, but delegate all the work to a Spring Bean that implements `Filter`.

Here is a picture of how `DelegatingFilterProxy` fits into the [`Filter`s and the `FilterChain`](#servlet-filters-review).

![delegatingfilterproxy](../_images/servlet/architecture/delegatingfilterproxy.png)

Figure 2. DelegatingFilterProxy

`DelegatingFilterProxy` looks up *Bean Filter<sub>0</sub>* from the `ApplicationContext` and then invokes *Bean Filter<sub>0</sub>*.
The pseudo code of `DelegatingFilterProxy` can be seen below.

Example 2. `DelegatingFilterProxy` Pseudo Code

Java

```
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	// Lazily get Filter that was registered as a Spring Bean
	// For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0
	Filter delegate = getFilterBean(someBeanName);
	// delegate work to the Spring Bean
	delegate.doFilter(request, response);
}
```

Kotlin

```
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
	// Lazily get Filter that was registered as a Spring Bean
	// For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0
	val delegate: Filter = getFilterBean(someBeanName)
	// delegate work to the Spring Bean
	delegate.doFilter(request, response)
}
```

Another benefit of `DelegatingFilterProxy` is that it allows delaying looking `Filter` bean instances.
This is important because the container needs to register the `Filter` instances before the container can startup.
However, Spring typically uses a `ContextLoaderListener` to load the Spring Beans which will not be done until after the `Filter` instances need to be registered.

## FilterChainProxy

Spring Security’s Servlet support is contained within `FilterChainProxy`.`FilterChainProxy` is a special `Filter` provided by Spring Security that allows delegating to many `Filter` instances through [`SecurityFilterChain`](#servlet-securityfilterchain).
Since `FilterChainProxy` is a Bean, it is typically wrapped in a [DelegatingFilterProxy](#servlet-delegatingfilterproxy).

![filterchainproxy](../_images/servlet/architecture/filterchainproxy.png)

Figure 3. FilterChainProxy

## SecurityFilterChain

[`SecurityFilterChain`](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/SecurityFilterChain.html) is used by [FilterChainProxy](#servlet-filterchainproxy) to determine which Spring Security `Filter`s should be invoked for this request.

![securityfilterchain](../_images/servlet/architecture/securityfilterchain.png)

Figure 4. SecurityFilterChain

The [Security Filters](#servlet-security-filters) in `SecurityFilterChain` are typically Beans, but they are registered with `FilterChainProxy` instead of [DelegatingFilterProxy](#servlet-delegatingfilterproxy).`FilterChainProxy` provides a number of advantages to registering directly with the Servlet container or [DelegatingFilterProxy](#servlet-delegatingfilterproxy).
First, it provides a starting point for all of Spring Security’s Servlet support.
For that reason, if you are attempting to troubleshoot Spring Security’s Servlet support, adding a debug point in `FilterChainProxy` is a great place to start.

Second, since `FilterChainProxy` is central to Spring Security usage it can perform tasks that are not viewed as optional.
For example, it clears out the `SecurityContext` to avoid memory leaks.
It also applies Spring Security’s [`HttpFirewall`](exploits/firewall.html#servlet-httpfirewall) to protect applications against certain types of attacks.

In addition, it provides more flexibility in determining when a `SecurityFilterChain` should be invoked.
In a Servlet container, `Filter`s are invoked based upon the URL alone.
However, `FilterChainProxy` can determine invocation based upon anything in the `HttpServletRequest` by leveraging the `RequestMatcher` interface.

In fact, `FilterChainProxy` can be used to determine which `SecurityFilterChain` should be used.
This allows providing a totally separate configuration for different *slices* of your application.

![multi securityfilterchain](../_images/servlet/architecture/multi-securityfilterchain.png)

Figure 5. Multiple SecurityFilterChain

In the [Multiple SecurityFilterChain](#servlet-multi-securityfilterchain-figure) Figure `FilterChainProxy` decides which `SecurityFilterChain` should be used.
Only the first `SecurityFilterChain` that matches will be invoked.
If a URL of `/api/messages/` is requested, it will first match on `SecurityFilterChain<sub>0</sub>`'s pattern of `/api/**`, so only `SecurityFilterChain<sub>0</sub>` will be invoked even though it also matches on `SecurityFilterChain<sub>n</sub>`.
If a URL of `/messages/` is requested, it will not match on `SecurityFilterChain<sub>0</sub>`'s pattern of `/api/**`, so `FilterChainProxy` will continue trying each `SecurityFilterChain`.
Assuming that no other, `SecurityFilterChain` instances match `SecurityFilterChain<sub>n</sub>` will be invoked.

Notice that `SecurityFilterChain<sub>0</sub>` has only three security `Filter`s instances configured.
However, `SecurityFilterChain<sub>n</sub>` has four security `Filter`s configured.
It is important to note that each `SecurityFilterChain` can be unique and configured in isolation.
In fact, a `SecurityFilterChain` might have zero security `Filter`s if the application wants Spring Security to ignore certain requests.

## Security Filters

The Security Filters are inserted into the [FilterChainProxy](#servlet-filterchainproxy) with the [SecurityFilterChain](#servlet-securityfilterchain) API.
The [order of `Filter`](#servlet-filters-review)s matters.
It is typically not necessary to know the ordering of Spring Security’s `Filter`s.
However, there are times that it is beneficial to know the ordering

Below is a comprehensive list of Spring Security Filter ordering:

* ChannelProcessingFilter

* WebAsyncManagerIntegrationFilter

* SecurityContextPersistenceFilter

* HeaderWriterFilter

* CorsFilter

* CsrfFilter

* LogoutFilter

* OAuth2AuthorizationRequestRedirectFilter

* Saml2WebSsoAuthenticationRequestFilter

* X509AuthenticationFilter

* AbstractPreAuthenticatedProcessingFilter

* CasAuthenticationFilter

* OAuth2LoginAuthenticationFilter

* Saml2WebSsoAuthenticationFilter

* [`UsernamePasswordAuthenticationFilter`](authentication/passwords/form.html#servlet-authentication-usernamepasswordauthenticationfilter)

* OpenIDAuthenticationFilter

* DefaultLoginPageGeneratingFilter

* DefaultLogoutPageGeneratingFilter

* ConcurrentSessionFilter

* [`DigestAuthenticationFilter`](authentication/passwords/digest.html#servlet-authentication-digest)

* BearerTokenAuthenticationFilter

* [`BasicAuthenticationFilter`](authentication/passwords/basic.html#servlet-authentication-basic)

* RequestCacheAwareFilter

* SecurityContextHolderAwareRequestFilter

* JaasApiIntegrationFilter

* RememberMeAuthenticationFilter

* AnonymousAuthenticationFilter

* OAuth2AuthorizationCodeGrantFilter

* SessionManagementFilter

* [`ExceptionTranslationFilter`](#servlet-exceptiontranslationfilter)

* [`FilterSecurityInterceptor`](authorization/authorize-requests.html#servlet-authorization-filtersecurityinterceptor)

* SwitchUserFilter

## Handling Security Exceptions

The [`ExceptionTranslationFilter`](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/access/ExceptionTranslationFilter.html) allows translation of [`AccessDeniedException`](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/access/AccessDeniedException.html) and [`AuthenticationException`](https://docs.spring.io/spring-security/site/docs/5.6.2/api//org/springframework/security/core/AuthenticationException.html) into HTTP responses.

`ExceptionTranslationFilter` is inserted into the [FilterChainProxy](#servlet-filterchainproxy) as one of the [Security Filters](#servlet-security-filters).

![exceptiontranslationfilter](../_images/servlet/architecture/exceptiontranslationfilter.png)

* ![number 1](../_images/icons/number_1.png) First, the `ExceptionTranslationFilter` invokes `FilterChain.doFilter(request, response)` to invoke the rest of the application.

* ![number 2](../_images/icons/number_2.png) If the user is not authenticated or it is an `AuthenticationException`, then *Start Authentication*.

  * The [SecurityContextHolder](authentication/architecture.html#servlet-authentication-securitycontextholder) is cleared out

  * The `HttpServletRequest` is saved in the [`RequestCache`](https://docs.spring.io/spring-security/site/docs/5.6.2/api/org/springframework/security/web/savedrequest/RequestCache.html).
    When the user successfully authenticates, the `RequestCache` is used to replay the original request.

  * The `AuthenticationEntryPoint` is used to request credentials from the client.
    For example, it might redirect to a log in page or send a `WWW-Authenticate` header.

* ![number 3](../_images/icons/number_3.png) Otherwise if it is an `AccessDeniedException`, then *Access Denied*.
  The `AccessDeniedHandler` is invoked to handle access denied.

|   |If the application does not throw an `AccessDeniedException` or an `AuthenticationException`, then `ExceptionTranslationFilter` does not do anything.|
|---|-----------------------------------------------------------------------------------------------------------------------------------------------------|

The pseudocode for `ExceptionTranslationFilter` looks something like this:

ExceptionTranslationFilter pseudocode

```
try {
	filterChain.doFilter(request, response); (1)
} catch (AccessDeniedException | AuthenticationException ex) {
	if (!authenticated || ex instanceof AuthenticationException) {
		startAuthentication(); (2)
	} else {
		accessDenied(); (3)
	}
}
```

|**1**|You will recall from [A Review of `Filter`s](#servlet-filters-review) that invoking `FilterChain.doFilter(request, response)` is the equivalent of invoking the rest of the application.<br/>This means that if another part of the application, (i.e. [`FilterSecurityInterceptor`](authorization/authorize-requests.html#servlet-authorization-filtersecurityinterceptor) or method security) throws an `AuthenticationException` or `AccessDeniedException` it will be caught and handled here.|
|-----|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|**2**|                                                                                                                                                                                               If the user is not authenticated or it is an `AuthenticationException`, then *Start Authentication*.                                                                                                                                                                                               |
|**3**|                                                                                                                                                                                                                                    Otherwise, *Access Denied*                                                                                                                                                                                                                                    |

[Getting Started](getting-started.html)[Authentication](authentication/index.html)

