In this post, we will look in to the Spring security authentication providers. This post will focus on the DaoAuthenticationProvider which we will use for our login process.
1. Spring Security Authentication Providers
Authentication providers are responsible to perform a specific authentication. Spring security provides several AuthenticationProvider
. Remember these AuthenticationProviders
can’t execute directly, but spring security uses ProviderManager
class which delegates to a list of configured authentication providers.
public interface AuthenticationProvider {
Authentication authenticate(Authentication authentication) throws AuthenticationException;
boolean supports(Class<?> authentication);
}
Our application configuration will determine what all authentication providers will be executed for given application (Will cover in this article). For a successful authentication, it will return a fully populated Authentication object, else it will throw an exception.
2. DaoAuthenticationProvider
For a standard login process, Spring security needs the customer information. Every project is unique in terms of the data model and how the customer data stored in the system.
- Some application can use email id as unique and login id.
- Other application design can let customer choose login id of their choice.
- For an intranet application, your employee id is your login id.
There should be a way to feed this information to the Spring security. In this article, we will look at the DaoAuthenticationProvider to authenticate customer using username and password. You can also use the JDBC authentication. DaoAuthenticationProvider
use the UserDetailsService
to authenticate a username and password.
2.1 UserDetailsService
For the DaoAuthenticationProvider, spring security needs a way to retrieving user information using the and other attributes for authenticating with a username and password. Spring security provide UserDetailsService interface. This interface contains only one method.
public interface UserDetailsService {
UserDetails loadUserByUsername(String var1) throws UsernameNotFoundException;
}
We can define custom authentication by exposing a custom UserDetailsService
as a bean. Our custom user service can load user based on our data model. In our case, we have defined email is as login id. Let’s define UserDetailsService
to load and provide the user data to the spring security. We will add this to our application available on GitHub.
@Service
public class CustomUserDetailService implements UserDetailsService {
@Autowired
UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
final UserEntity customer = userRepository.findByEmail(email);
if (customer == null) {
throw new UsernameNotFoundException(email);
}
UserDetails user = User.withUsername(customer.getEmail())
.password(customer.getPassword())
.authorities("USER").build();
return user;
}
}
So our custom UserDetailsService
service is using the UserRepository
to load the customer information by email. We also need to extend the UserRepository
interface to add the findByEmail method. Main confirmations are complete. It’s time to configure our DaoAuthenticationProvider
.
For more detail, please read Spring Security UserDetailsService
3. DaoAuthenticationProvider Workflow
Before we configure our application, let’s look at how the authentication provider works:
- We create an
UsernamePasswordAuthenticationTokem
from the supplied username and password. - We pass this token to the authentication manager.
- The provider manager will delegate the authentication to the
DaoAuthenticationProvider
including the authentication token. - The
DaoAuthenticationProvider
use the customUserDetailsService
service to get the customer information from the database. - On successful authentication, the authentication object will contain the fully populated object including the authorities details.
- The returned
UsernamePasswordAuthenticationToken
will be set on the SecurityContextHolder by the authentication Filter.
4. Authentication Provider Configurations
The last step is to configure the authentication provider. We want the DaoAuthenticationProvider
to use our customer UserDetailsService
service to get the user information. This is done by extending the WebSecurityConfigurerAdapter
.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import javax.annotation.Resource;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource
private UserDetailsService userDetailsService;
@Autowired
PasswordEncoder passwordEncoder;
@Bean
public DaoAuthenticationProvider authProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(passwordEncoder);
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authProvider());
}
}
- The
@EnableWebSecurity
enable Spring Security’s web security support and provide the Spring MVC integration. - We are extending
WebSecurityConfigurerAdapter
class, which provides a convenient base class for creating aWebSecurityConfigurer
instance. - Injecting custom
UserDetailsService
in theDaoAuthenticationProvider
. - We are encoding the password during registration. Need to inject the same password encoder to the authentication provider, else our login process will not work as expected.
Summary
In this article, we looked at the spring security authentication providers. We covered the following points.
- What is spring security authentication providers?
- Why we need authentication providers?
- We checked details for the DaoAuthenticationProvider.
- Checked how DaoAuthenticationProvider use an UserDetailsService to get the user details from the database.
- How to configure authentication provider for our application.
The source code for this series is available on the GitHub.