This section discusses the high-level architecture of Spring Security in servlet-based applications.
A brief description of filters
Spring Security's servlet support is based on Filter
servlet instances, so it's useful to first look at the role of Filter
in general. The figure below shows a typical layered structure of handlers for a single HTTP request.

The client sends a request to the application, and the container creates a FilterChain
, which contains instances of a Filter
and a Servlet
that should process a HttpServletRequest
based on the request URI path. In a Spring MVC application, Servlet
is an instance of DispatcherServlet
. Only one Servlet
can handle one HttpServletRequest
and HttpServletResponse
. However, you can use more than one Filter
to:
Prevent calls to downstream
Filter
orServlet
. In this case,Filter
typically recordsHttpServletResponse
.Changes to
HttpServletRequest
orHttpServletResponse
used by subsequentFilter
andServlet
The power of Filter
depends on FilterChain
, which is passed into it.
FilterChain
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// do something before executing the rest of the application
chain.doFilter(request, response) ;// invoke the rest of the application
// do something after the rest of the application is executed
}
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
// do something before executing the rest of the application
chain.doFilter(request, response)// invoke the rest of the application
// do something after the rest of the application has executed
}
Because the Filter
only affects the underlying Filter
and Servlet
, the order in which each Filter
is called is extremely important.
DelegatingFilterProxy
Spring provides an implementation of Filter
titled DelegatingFilterProxy
, which allows you to establish a bridge between the lifecycle of a servlet container and ApplicationContext
from Spring. The servlet container allows you to register Filter
instances using its own standards, but it does not know about the beans defined by Spring. DelegatingFilterProxy
can be registered through standard servlet container mechanisms, but delegates all the work to the Spring bean that implements Filter
.
Here is how DelegatingFilterProxy is used
fits into a schema with Filter
and FilterChain
instances.

DelegatingFilterProxy
looks up Bean Filter0 in ApplicationContext
and then calls Bean Filter0. The pseudo code for DelegatingFilterProxy
is shown below.
DelegatingFilterProxy
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
// In deferred mode, we get the filter that was registered as a Spring bean
// For the example in DelegatingFilterProxy, the delegate is instance Bean Filter0
Filter delegate = getFilterBean(someBeanName);
// delegate the work to the Spring bean delegate.doFilter(request, response);
}
fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
// In deferred mode, we get the filter that was registered as a Spring bean
// For the example in DelegatingFilterProxy, the delegate is an instance of Bean Filter0
val delegate: Filter = getFilterBean(someBeanName)
// delegate work with the Spring bean delegate.doFilter(request, response)
}
Another advantage of DelegatingFilterProxy
is that it allows you to defer the search for instances of Filter
beans. This is important because the container needs to register Filter
instances before running the container. However, Spring typically uses ContextLoaderListener
to load Spring beans, which only happens after Filter
instances have been registered.
FilterChainProxy
Servlet Facilities in Spring Security they are contained in FilterChainProxy
. FilterChainProxy
is a specialized Filter
provided by Spring Security that allows you to delegate authority to multiple Filter
instances via <SecurityFilterChain
. Since FilterChainProxy
is a bean, it is usually wrapped in DelegatingFilterProxy.

SecurityFilterChain
SecurityFilterChain
is used by FilterChainProxy to determine which Filter
from Spring Security should be called for a given request.

Security filters in SecurityFilterChain
are usually beans, but they are registered in FilterChainProxy
instead of DelegatingFilterProxy
. FilterChainProxy
provides several advantages over registering directly with the servlet container or DelegatingFilterProxy. First, it provides the starting point for all servlet support in Spring Security. For this reason, if you are trying to troubleshoot Spring Security's servlet support, a good place to start is by adding a debug point to FilterChainProxy
.
Secondly, because FilterChainProxy
is central to the use of Spring Security, it can perform tasks that are not considered optional. For example, it cleans up SecurityContext
to avoid memory leaks. It also uses HttpFirewall
from Spring Security to protect applications from certain types of attacks.
It also provides greater flexibility in determining when to call SecurityFilterChain
. In a servlet container, Filter
instances are called based on the URL only. However, FilterChainProxy
can determine the call based on anything in HttpServletRequest
using the RequestMatcher
interface.
In fact, FilterChainProxy
can be used to determine which SecurityFilterChain
should be used. This allows you to provide completely separate configuration for different parts of your application.

In the picture with several SecurityFilterChain, the FilterChainProxy
instance decides which SecurityFilterChain
should be used. Only the first matching SecurityFilterChain
will be called. If the URL /api/messages/
is requested, it will first be matched against the pattern SecurityFilterChain0
via /api/**
, so only SecurityFilterChain0
will be called, even if it also matches SecurityFilterChainn
. If the /messages/
URL is requested, it will not be matched against the SecurityFilterChain0
pattern via /api/**
, so FilterChainProxy
will continue to iterate over each SecurityFilterChain
. It is assumed that other instances of SecurityFilterChain
that match SecurityFilterChainn
will not be called.
Note that in SecurityFilterChain0
only three instances of Filter
are configured. However, there are four Filter
s configured in the SecurityFilterChainn
. It is important to note that each SecurityFilterChain
can be unique and configured in isolation. In fact, SecurityFilterChain
can have zero Filter
instances if the application wants Spring Security to ignore certain requests.
Security Filters
Spring Security filters are added to FilterChainProxy via the SecurityFilterChain API. The order of Filter
instances matters. Typically there is no need to know the order of Filter
in Spring Security. However, in some cases it is useful to know what order they are in.
The following is a complete ordered list of Spring Security filters:
ForceEagerSessionCreationFilter
ChannelProcessingFilter
WebAsyncManagerIntegrationFilter
SecurityContextPersistenceFilter
HeaderWriterFilter
CorsFilter
CsrfFilter
LogoutFilter
OAuth2AuthorizationRequestRedirectFilter
Saml2WebSsoAuthenticationRequestFilter
X509AuthenticationFilter
AbstractPreAuthenticatedProcessingFilter
CasAuthenticationFilter
OAuth2LoginAuthenticationFilter
Saml2WebSsoAuthenticationFilter
UsernamePasswordAuthenticationFilter
OpenIDAuthenticationFilter
DefaultLoginPageGeneratingFilter
DefaultLogoutPageGeneratingFilter
ConcurrentSessionFilter
DigestAuthenticationFilter
BearerTokenAuthenticationFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
OAuth2AuthorizationCodeGrantFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
SwitchUserFilter
Security exception handling
ExceptionTranslationFilter
allows conversion AccessDeniedException
and AuthenticationException
in HTTP responses.
ExceptionTranslationFilter
is added to FilterChainProxy in quality of one of the security filters.

1 First
ExceptionTranslationFilter
accessesFilterChain.doFilter(request, response)
to call the rest of the application.2 If the user is not authenticated or an
AuthenticationException
occurs, then run authentication procedure.TheSecurityContextHolder is cleared
HttpServletRequest
is saved inRequestCache
. Once the user is successfully authenticated,RequestCache
will be used to replay the original request.AuthenticationEntryPoint
is used to request credentials client data. For example, it could redirect to a login page or send aWWW-Authenticate
header.
3 Otherwise, if
AccessDeniedException
occurs, access will be denied.AccessDeniedHandle
r
is called to handle access denial.
If the application does not throw an AccessDeniedException
or AuthenticationException
, then the ExceptionTranslationFilter
does nothing.
The pseudocode for the ExceptionTranslationFilter
looks something like this:
try {
filterChain.doFilter(request, response);
} catch (AccessDeniedException | AuthenticationException ex) {
if (!authenticated || ex instanceof AuthenticationException) {
startAuthentication();
} else {
accessDenied();
}
}
- From the brief description of
Filter
instances, you may recall that callingFilterChain.doFilter(request, response)
is equivalent to calling the rest of the application. This means that if another part of the application (e.g.FilterSecurityInterceptor
or security method) throws anAuthenticationException
orAccessDeniedException
, then those exceptions will be caught and handled at this stage. - If the user is not authenticated or an
AuthenticationException
is thrown, then run the authentication procedure. - Otherwise access will be denied
GO TO FULL VERSION