Spring Security Architecture fundamentals
Authentication and authorization are fundamental to the security of web applications. While authentication determines if the user can be identified by the system, Authorization determines if the user has the access to the specific resource.
The authentication, as well as authorization design paradigm, is continuously evolving. The main reason behind it is the continuous evolution in different methods of exploits used against the applications.
Spring security tries to solve this problem by packaging all the possible solutions together.
The purpose of this article is to provide a high level understanding of spring security architecture for Servlet applications. It may not help you to immediately implement spring security in your application but it would definitely help you in the subsequent steps when you dive deeper.
Filter pattern in spring security
Spring Security for web applications uses the filter pattern to implement different types of security solutions. At the very core of it are Servlet filters. Spring framework provides DelegatingFilterProxy filter and Spring security adds FilterChainProxy filter on top of it. Both these filters are pivotal in Spring security.
Spring Security Filter architecture
DelegatingFilterProxy Filter
Similar to the Servlet filters, the Spring Security filters implement Filter interface but they are also Spring beans which mean they are managed by Spring ApplicationContext.
Since these filters are not registered via Servlet container standards(configured in web.xml), the servlet Container is not aware of them.
Spring provides DelegatingFilterProxy filter which sits in the filter chain. It bridges the Servlet containers lifecycle and Spring ApplicationContext.
When a request is delegated to DelegatingFilterProxy. It looks up bean filters from the application context and then invokes the relevant bean filter. DelegatingFilterProxy filter also allows for delayed bean Filter lookup.
FilterChainProxy Filter
Spring security provides a special bean filter named as FilterChainProxy. This filter is a single entry point that enables spring security for a web application.
It allows delegating requests through a set of filters bundled as SecurityFilterChain. In order to determine which Spring Security Filter’s should be invoked, FilterChainProxy uses SecurityFilterChain. There could be multiple SecurityFilterChains present.
FilterChainProxy is also used to perform some security-specific tasks such as clearing SecurityContext. FilterChainProxy is more flexible than traditional Servlet Filters. It can determine which securityFilterchain to invoke by leveraging the RequestMatcher interface.
SecurityFilterChain
It is a list of security filters that are also Spring managed beans. These are registered with FilterChainProxy. The advantage of being registered with SecurityFilterChain are following:
FilterChainProxy leverages RequestMatcher interface to determine invocation based upon anything in ServletRequest including the URL. In case of multiple SecurityFilterChains, FilterChainProxy can determine which SecurityFilterChain should be used. It also clears SecurityContext to avoid any memory leaks.
Customizing the default SecurityFilterChain
Spring security creates an instance of WebSecurity via WebSecurityConfiguration. WebSecurity is responsible for creating an instance of FilterChainProxy filter.
We can create customizations to the built-in functionality by —
- Either extending
WebSecurityConfigurerAdapterand exposing it as a Configuration - Or implementing
WebSecurityConfigurerand exposing it as a Configuration.
This configuration is imported when using @EnableWebSecurity annotation.
AuthenticationEntryPoint
- When a client sends a request without authentication credentials, an implementation of
AuthenticationEntryPointwill be used to send the response to the client to ask for credentials.
The AuthenticationEntryPoint implementation might perform a redirect to a log-in page, respond with an WWW-Authenticate header, etc.
AbstractAuthenticationProcessingFilter
This is the base filter used for authenticating the requests. When the user request comes in
- If it has credentials pre-populated, the implementation of
AbstractAuthenticationProcessingFilteris directly called. - If the credentials are not populated, the implementation of
AuthenticationEntryPointis called first to request credentials from the client- After that
AbstractAuthenticationProcessingFilteris directly called.
- After that
Authentication Architecture API
AuthenticationManager
This is a strategy interface that provides the API to perform authentication. It is invoked by spring security filters. The authentication object that is returned is set on SecurityContextHolder.
It basically checks the authentication and decides
- If the principle is valid
- If the principle is invalid
- If the authentication is null
In case, Security Filters are not used such as when using user-defined filters, Authentication can be set on SecurityContextHolder manually.
ProviderManager
It is a common implementation of AuthenticationManager. It delegates to a list of AuthenticationProviders. Each AuthenticationProvider has the opportunity to authenticate as well as to show that it can not.
It also allows an optional parent AuthenticationManager. If no AuthenticationProvider is provided, the parent AuthenticationManager is consulted for authentication.
If no authenticationProviders can authenticate, authentication fails.
AuthenticationProvider
Its implementations performs a specific type of authentication. For example, DaoAuthenticationProvider supports username/password based authentication while JwtAuthenticationProvider supports authenticating a JWT token.
SecurityContextHolder
This object contains the authentication information about a request.
It contains SecurityContext which by default is a threadLocal object. thus every request thread has its own SecurityContext object.
SecurityContextHolder API Diagram
Security Context
The securityContext object contains Authentication Object. The Authentication object serves two main purposes within Spring Security —
It acts as an input to
AuthenticationManagerto provide the credentials a user has provided to authenticate.AuthenticationManager.authenticate(Authentication authentication)It also represents the currently authenticated user. The current
Authenticationcan be obtained from theSecurityContext.SecurityContextHolder.getContext().getAuthentication()Authentication provides the below details regarding an authenticated user:
Principal— which identifies the user. When authenticating with a username/password this is often an instance ofUserDetailsinterface.Credentials— is basically the passwordGrandtedAuthorities— provide the authorization scope for the principal. It is fine grained scope for authorization.GrantedAuthoritiescan be obtained from theAuthentication.getAuthorities()method.
if you have reached this far and want to explore more on spring security. Here are a few posts to get you going.





