Sooner or later everyone has to add security to their projects. In the spring framework, you do that by taking the help of Spring Security. In this article, we will try to understand how does Spring Security works internally and in the subsequent articles, we will see the implementation.
Before understanding Spring Security we need to understand some keywords related to security implementation.
- Authentication: Authentication is the process of recognizing a user's identity; i.e, verifying that if the user is who he claims to be, typically done with username and password.
- Authorization: Authorization is the security mechanism to establish the access level/privileges for users to access resources like files, services, data etc.
- Filter: A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. Spring Security maintains a filter chain internally where each of the filters has a particular responsibility and filters are added or removed from the configuration as per the need.
- Authentication Manager: It is an interface having a single method authenticate. It attempts to authenticate the
Authenticationobject and to do so it takes the help of the
- Provider Manager: It is the most commonly used implementation of Authentication Manager. It delegates the request to a list of Authentication Provider.
- Authentication Provider: It performs a specific type of authentication. For example,
DaoAuthenticationProvidersupports username/password based authentication while
JwtAuthenticationProvidersupports authenticating a JWT token.
- UserDetailService: It is used by
DaoAuthenticationProviderfor retrieving the username and password and other attributes for authenticating.
- SecurityContext: The SecurityContext is used to store the details of the currently authenticated user, also known as a principal.
Connecting the dots...
Let's assume we have a client and a server application and in the server application, we have enabled spring security. Now if the Client wants to access some resource from the server it won't be able to do so as the request is not authenticated yet. So we need someone to catch the request before reaching the server application and authenticate it. This is done by Filters.
The client will send the request containing username and password to the server which will be filtered by
Filters, more accurately
DelegatingFilterProxy will convert the servlet request to an
Authentication object. The authentication object will primarily contain a
principal or username and
credential or password.
But filters don't contain logic to authenticate the user. So filter will delegate the request to
AuthenticationManager has a method authenticate which takes
Authentication object as a parameter.
AuthenticationManager will further delegate the request to
AuthenticationProvider, but to do so it will take the help of
Spring security has multiple authentication providers based on various authentication mechanisms. Assuming Authentication Provider 1 (AP1) is based on JWT, Authentication Provider 2 (AP2) is OAuth based and Authentication Provider 3 (AP3) is DAO implementation i.e, username password based.
Authentication Providers have method
support that returns true if it supports the authentication mechanism else false if it doesn't support it.
ProviderManager will one by one delegate the request to different APs and will check if it supports the authentication method.
In our example, the Provider Manager will first reach out to AP1; since it's JWT based it will return false. Similarly, AP2 will also return false as it is OAuth based. Then
ProviderManager will delegate the request to AP3 that supports username password based authentication.
Now, AP3 will take forward the process of authentication. To authenticate AP3 should have the details of the user. To fetch the user details from an external source like DB or memory or cache AP will take the help of
UserDetailService will fetch the details of the user based on username and return the details to AP3. AP3 will authenticate the user details and will return a valid authenticated object to
ProviderManager will return the authenticated object to
The filter will send this object to
SecurityContext and it would be stored there. And the request will redirect to the server-side application and the client will be given access to the resource.
In a case, if the user details are not found or are invalid credentials are sent from the client, a respective exception will be thrown and nothing will be stored in SecurityContext and access to the resource will be denied.
In this article, we learnt how Spring Security works and how a user is authenticated based on username and password.
In the successive articles, we will see the implementation of spring security with different mechanisms.