How does spring security works internally?
Spring security is enabled by itself by just adding the spring security starter jar. But, what happens internally and how does it make our application secure? To answer this question, let us understand a few basic terms that are related to spring security.
- Principal: Currently logged in user.
- Authentication: Confirming truth of credentials.
- Authorisation: Defines access policy for the Principal.
- GrantedAuthority: Permission granted to the principal.
- AuthenticationManager: Controller in the authentication process. Authenticates user saved in memory via authenticate().
- AuthenticationProvider: Interface that maps to a data store that stores your data.
- Authentication Object: Object that is created upon authentication. It holds the login credentials. It is an internal spring security interface.
- UserDetails: Data object that contains the user credentials but also the role of that user.
- UserDetailsService: Collects the user credentials, authorities (roles) and build an UserDetails object.
The Spring Security Architecture
When we add the spring security starter jar, it internally adds Filter to the application. A Filter is an object that is invoked at pre-processing and post-processing of a request. It can manipulate a request or even can stop it from reaching a servlet. There are multiple filters in spring security out of which one is the Authentication Filter, which initiates the process of authentication.
Once the request passes through the authentication filter, the credentials of the user are stored in the Authentication object. Now, what actually is responsible for authentication is AuthenticationProvider (Interface that has method authenticate()). A spring app can have multiple authentication providers, one may be using OAuth, others may be using LDAP. To manage all of them, there is an AuthenticationManager.
The authentication manager finds the appropriate authentication provider by calling the supports() method of each authentication provider. The supports() method returns a boolean value. If true is returned, then the authentication manager calls its authenticate() method.
After the credentials are passed to the authentication provider, it looks for the existing user in the system by UserDetailsService. It returns a UserDetails instance which the authentication provider verifies and authenticates. If success, the Authentication object is returned with the Principal and Authorities otherwise AuthenticationException is thrown.