I am trying to create a project for learning more about Spring Security and I am trying to follow a flow that starts from the Security Filter Chain -> Authentication Manager -> Authentication Provider -> UserDetailsService -> DB
My Security Config:
@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig{
DetailService userDetailService;
@Bean
public PasswordEncoder getPassWordEncoder() {
return new BCryptPasswordEncoder(15);
}
@Bean
DaoAuthenticationProvider authProvider(){
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailService);
authProvider.setPasswordEncoder(getPassWordEncoder());
return authProvider;
}
@Bean
public ProviderManager authManagerBean(HttpSecurity security) throws Exception {
return (ProviderManager) security.getSharedObject(AuthenticationManagerBuilder.class)
.authenticationProvider(authProvider()).
build();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeHttpRequests(authorize -> authorize.requestMatchers("/login/**", "/css/**", "/js/**", "/registration/**").permitAll()
.anyRequest().authenticated())
.csrf().disable()
.formLogin(form -> form.loginPage("/login")
.defaultSuccessUrl("/home")
.failureForwardUrl("/login-failure?error=true"))
.logout().permitAll();
return http.build();
}
}
Controller:
@RequestMapping("/login.html")
public String login(@RequestBody UserDTO dto) {
Authentication authentication = authenticationManager.
authenticate(new UsernamePasswordAuthenticationToken(dto.getUsername(), dto.getPassword()));
return "/login.html";
}
From what I've read the authentication/provider manager receives an authentication object, which is created from the username & password credentials from the login form that the controller handles.
This is what I've implemented in the controller.
Questions:
- How do I proceed to pass this authentication object created from the controller to the provider manager? (I know this is probably wrong but) Do I add another parameter to the AuthenticationManager @bean of type Authentication?
- I was also a little unsteady on the
ProviderManager
is this done correctly?
Thank you all very much for reading :)
CodePudding user response:
I was also a little unsteady on the ProviderManager is this done correctly?
Instead of relying on Spring Security internals to create the AuthenticationManager
(hard to understand and debug), you can create one by yourself since you are not using any authentication mechanism that Spring Security provides out of the box.
You can change your ProviderManager
bean to:
@Bean
public ProviderManager authManagerBean(AuthenticationProvider provider) {
return new ProviderManager(provider);
}
or, even better, because you won't use the AuthenticationProvider
bean alone do not expose it as a bean, instead, do this:
@Bean
public AuthenticationManager authenticationManager(){
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailService);
authProvider.setPasswordEncoder(getPassWordEncoder());
return new ProviderManager(authProvider);
}
How do I proceed to pass this authentication object created from the controller to the provider manager? (I know this is probably wrong but) Do I add another parameter to the AuthenticationManager @bean of type Authentication?
I don't think I follow what you are asking. The Authentication
object, in your case a UsernamePasswordAuthenticationToken
is being passed to the ProviderManager
when you call authenticationManager.authenticate(...)
.