I have some confusion when working with authentication in spring security. There are two ways of authentication.
- By overriding configure method
- By implementing bean instance for AuthenticationProvider
I need to know what is the difference between them and the pros and cons of using each.
1.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
@Bean
public BCryptPasswordEncoder getBCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationProvider authenticationProvider(){
DaoAuthenticationProvider daoAuthenticationProvider=new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(new BCryptPasswordEncoder());
return daoAuthenticationProvider;
}
If you are not sure of the spring security filter chain, see this answer. How Spring Security Filter Chain works
Here is a screenshot I recently took when I was setting up demo ldap + in-memory auth.
As you can see, in the end, we want a type of AuthenticationFilter
in our spring security filter chain. That filter is responsible for receiving the login request and decide the if authentication successful or not.
AuthenticationFilter
has a reference to AuthenticationManger
and AuthenticationManger
implementation (which is called ProviderManager
) does not do authentication directly. Instead AuthenticationManger
implementations can have a list of AuthenticationProvider
s and depend on the type authentication request, it asks the corresponding AuthenticationProvider
in its list do the authentication.
AuthenticationFilter
delegates to AuthenticationManger
(.ie ProviderManager
) which in turn delegates to one
of AuthenticationProvider
So here is sample. Just for demo purpose, I am duplicating your authenticationProvider()
definition and see how the AuthenticationManger
.ie ProviderManager
looks
@Override
protected void configure(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(authenticationProvider1())
.authenticationProvider(authenticationProvider2());
}
@Bean("my-auth-provider-1")
public AuthenticationProvider authenticationProvider1(){
DaoAuthenticationProvider provider=new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService());
return provider;
}
@Bean("my-auth-provider-2")
public AuthenticationProvider authenticationProvider2(){
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(userDetailsService());
return provider;
}
Note
I have simplified a bit here. Actually ProviderManager
can have parent too. But effectively it has a list of providers. See https://spring.io/guides/topicals/spring-security-architecture