Authentication vs Authorization
Authentication
the process of validating your credentials (such as User username and password) to verify your identity and whether you are the person you claim to be, or not.
Or simply put, Authentication is about knowing who you are.
Authorization
the process to determine whether the authenticated user has access to a particular resource.
Or simply put, Authorization is about knowing whether you have the right to access what you want or not.
Spring Security Architecture (simple ver.)
SecurityFilterChain
Spring Security maintains a filter chain internally where each of the filters is invoked in a specific order. Each filter will try to process the request and retrieve authentication information from it. For example, we have the UsernamePasswordAuthenticationFilter which is used in case of a POST request with username and password parameters (typically with a login page).
AuthenticationManager
This is an interface whose implementation (ProviderManager) has a list of configured AuthenticationProviders that are used for authenticating user requests.
AuthenticationProvider
An AuthenticationProvider is an abstraction for fetching user information from a specific repository (like a database, LDAP, custom third party source, etc.). It uses the fetched user information to validate the supplied credentials. (e.g: DaoAuthenticationProvider, LdapAuthenticationProvider, OpenIDAuthenticationProvider …)
When talking about AuthenticationProvider, we usually come across the UserDetailsService. There is often a confusion between both, although they have different roles.
AuthenticationProvider authenticates (compares) the request credentials against system credentials.
UserDetailsService is purely a DAO for user data and performs no other function other than to supply that data that match with user provided Username. It does not tell the application whether authentication is successful or failed.
Authentication Flow
[Step 1]
When an incoming request reaches our system, Spring Security starts by choosing the right security filter to process that request:
Is the request a POST containing username and password elements?
=> UsernamePasswordAuthenticationFilter is chosen.
Is the request having a header “Authorization : Basic base64encoded(username:password)”? => BasicAuthenticationFilter is chosen… and so the chaining goes on.
[Step 2]
When a filter had successfully retrieved Authentication informations from the request,
the AuthenticationManager is invoked to authenticate the request.
Via its implementation, the AuthenticationManager goes through each of the provided AuthenticationProvider(s) and try to authenticate the user based on the passed Authentication Object.
[Step 3]
When the Authentication is successful, and a matching user is found, an Authentication Object containing the user Authorities (which will be used to manage the user access to the system’s resources) is returned and set into the SecurityContext.
Spring Security Architecture (in-depth ver.)
1. Received the Http Request
Spring security has a series/chain of filters. Therefore when a request comes, it will go through a chain of filters for authentication and authorization purposes. When there is an user authentication request, that will also go through the chain of filters as usual until it finds the relevant Authentication Filter based on the authentication mechanism/model.
2. Creates AuthenticationToken based on user credentials
Once the authentication request is received by the relevant AuthenticationFilter, it extracts the username and password from the received request (most of the authentication mechanism require username and password). After that it creates an Authentication object based on the extracted user credentials.
If the extracted credentials are username and password, then UsernamePasswordAuthenticationToken will be created using username and password extracted/found.
3. Delegating created AuthenticationToken for AuthenticationManager
After creating the UsernamePasswordAuthenticationToken object, it will be used to invoke the authenticate method of the AuthenticationManager. AuthenticationManager is a just an interface and actual implementation is ProviderManager.
AuthenticationManager.java
public interface AuthenticationManager {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
}
ProviderManager has a list of configured AuthenticationProvider(s) that should be used for authenticating user requests. ProviderManager will go through each of the provided AuthenticationProvider(s) and try to authenticate the user based on the passed Authentication Object (e.g:- UsernamePasswordAuthenticationToken)
4. Trying to authenticate with list of AuthenticationProvider(s)
AuthenticationProvider tries to authenticate user with provided authentication object.
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}
Here are some of the existing authentication providers that comes with the framework:
- CasAuthenticationProvider
- JaasAuthenticationProvider
- DaoAuthenticationProvider
- OpenIDAuthenticationProvider
- RememberMeAuthenticationProvider
- LdapAuthenticationProvider
5. UserDetailsService Required?
Some of the AuthenticationProvider may use UserDetailsService for retrieving the user details based on the username. (e.g:- DaoAuthenticationProvider)
public interface UserDetailsService {
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
}
6 and 7. UserDetails or User Object?
UserDetailsService will retrieve the UserDetails (actual implementation is User) based on the username.
8. Authentication Object Or AuthenticationException?
If the user is successfully authenticated, then the fully populated Authentication object will be returned. Otherwise an AuthenticationException will be thrown.
According to the AuthenticationProvider interface, AuthenticationProvider will exactly return fully populated authentication object (on successful authentication) or throw an AuthenticationException (on authentication failure).
Fully populated Authentication Object
- authenticated – true
- grant authorities list
- user credentials (username only)
If any AuthenticationException is thrown, that will be handled by the configured AuthenticationEntryPoint that supports for the authentication mechanism.
9. Authentication is done!
AuthenticationManager will return the obtained fully populated Authentication object back to the relevant Authentication Filter.
10. Setting up Authentication Object in SecurityContext
Then the related AuthenticationFilter will store the obtained authentication object in the SecurityContext for future filter uses. (Use for Authorization Filters)
SecurityContextHolder.getContext().setAuthentication(authentication);
Reference:
https://medium.com/@haytambenayed/how-does-spring-security-work-internally-525d359d7af
https://chathurangat.wordpress.com/2017/08/23/spring-security-authentication-architecture/
'Backend > Spring' 카테고리의 다른 글
[Spring Boot/Gradle] spring-dev-tools 추가 (0) | 2025.01.20 |
---|---|
Java Validation, Spring Validation (0) | 2024.03.25 |
Spring Bean Life Cycle / 스프링 빈 생명주기 (0) | 2023.11.07 |
[Spring & Boot] Message 사용법 (0) | 2022.03.24 |
[Spring] 로그: JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message (0) | 2021.11.16 |
댓글