As far as I can understand when you want custom authentication in Spring Security you can either implement a custom AuthenticationProvider
or custom UserDetailsService
.
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
//.authenticationProvider(authProvider) // option 1
.userDetailsService(userDetailsService); // option 2
}
In the AuthenticationProvider you can check the username and password and return Authentication
with your custom object in it.
public Authentication authenticate(Authentication authentication){
if (checkUsernameAndPassword(authentication)) {
CustomUserDetails userDetails = new CustomUserDetails();
//add whatever you want to the custom user details object
return new UsernamePasswordAuthenticationToken(userDetails, password, grantedAuths);
} else {
throw new BadCredentialsException("Unable to auth against third party systems");
}
}
In the UserDetailsService
you get only the username and when you return the custom UserDeatails, the framework performs a check on the password.
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
CustomUserDetails user = new CustomUserDetails();
//add whatever you want to the custom user details object
return user;
}
Looks like both can produce similar results. So the question is what is the difference? When to user one vs the other?
You can use custom token based implementation, you can create a custom token that you can store in DB but JWT is a good choice.
Authentication Provider calls User Details service loads the User Details and returns the Authenticated Principal. Authentication Manager returns the Authenticated Object to Authentication Filter and Authentication Filter sets the Authentication object in Security Context .
The UserDetailsService interface is used to retrieve user-related data. It has one method named loadUserByUsername() which can be overridden to customize the process of finding the user. It is used by the DaoAuthenticationProvider to load details about the user during authentication.
The answer is inside your question. when you are using a different authentication system, and the password is not provided in your own database/data model, you have to use the AuthenticationProvider. for example, I've worked in a project that the customer had a centralized authentication system (CAS), so my system had no idea about the password, I had to implement the AuthenticationProvider and send the given password to the CAS, and act according to its answer.
But in another system, I was storing the password in my database, so all I had to do was implementing the UserDetailsService and check if the user exists in my database or not, spring-security had to do the rest.
From spring security documention, https://docs.spring.io/spring-security/site/docs/5.0.0.RC1/reference/htmlsingle/#overall-architecture
There is often some confusion about UserDetailsService. It is purely a DAO for user data and performs no other function other than to supply that data to other components within the framework. In particular, it does not authenticate the user, which is done by the AuthenticationManager. In many cases it makes more sense to implement AuthenticationProvider directly if you require a custom authentication process.
AuthenticationProvider and UserDetailsService have different purpose.
AuthenticationProvider authenticates(compares) the user(request) provided username and password against system User(This can be any system like DB which maintains list of registered users)
It is the responsiblity of UserDetailsService Implementation to get the System User Details that match with user provided Username. Here it just gets the users that have same username and does not tell the application whether authentication is successful or failed.
Example : Spring provides the following as a default setup to authenticate a user details against database
Have a look here to understand it better:
AuthenticationProvider - DaoAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider
UserDetailsService - JdbcDaoImpl
UserDetails - User
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With