I'm using spring security 5.7 and WebSecurityConfigurerAdapter is deprecated. I want use multiple Authentication Provider(Ldap and Dao) but ldap provider not working and spring security just call DaoAuthenticationProvider.
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration {
@Autowired
private JWTTokenFilter jwtTokenFilter;
@Autowired
private LdapAuthProvider ldapAuthProvider;
@Autowired
private UserService userService;
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userService);
authProvider.setPasswordEncoder(passwordEncoder());
return authProvider;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors()
.and().csrf().disable()
.headers().frameOptions().disable()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests().antMatchers("/api/test/**", "/auth/**", "/h2-console/**").permitAll()
.and().authorizeRequests().anyRequest().authenticated()
.and().addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
http.authenticationProvider(ldapAuthProvider);
http.authenticationProvider(authenticationProvider());
return http.build();
}
@Bean
public AuthenticationManager authenticationManager(
AuthenticationConfiguration authenticationConfiguration) throws Exception {
return authenticationConfiguration.getAuthenticationManager();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
when remove DaoAuthenticationProvider then LdapAuthProvider is work. what's the problem?
edit: i want use exposed AuthenticationManager in whole app like this:
@Autowired
private AuthenticationManager authenticationManager;
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody AuthRequest authRequest) {
if(authRequest.getUsername() == null || authRequest.getPassword() == null) {
return ResponseEntity.badRequest().build();
}
Authentication authenticate = null;
try {
authenticate = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
authRequest.getUsername(),
authRequest.getPassword()));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(401).build();
}
but this AuthenticationManager not contain my custom AuthenticationProvider
Below is an example of using two authentication providers (Ldap and Dao) in Spring Security 5.7. This is in the context of a traditional web application using form login. The trick was to explicitly set the AuthenticationManager
to use (i.e. ProviderManager
) in the filter chain and reference both authentication providers:
@Bean
public ActiveDirectoryLdapAuthenticationProvider getAdAuthProvider(CustomLdapUserDetailsMapper customLdapUserDetailsMapper) {
ActiveDirectoryLdapAuthenticationProvider authProvider = new ActiveDirectoryLdapAuthenticationProvider(domain, urls);
authProvider.setSearchFilter("(&(objectClass=user)(sAMAccountName={1}))");
authProvider.setUserDetailsContextMapper(customLdapUserDetailsMapper);
return authProvider;
}
@Bean
public DaoAuthenticationProvider getDaoAuthProvider(CustomDatabaseUserDetailsService customDatabaseUserDetailsService) {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(customDatabaseUserDetailsService);
provider.setPasswordEncoder(new BCryptPasswordEncoder());
return provider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, ActiveDirectoryLdapAuthenticationProvider adAuthProvider, DaoAuthenticationProvider dbAuthProvider) throws Exception {
http.authorizeRequests()
.antMatchers("/").permitAll()
...
.anyRequest().hasAuthority("ADMIN")
.and().formLogin().loginPage("/login").permitAll()
.and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout")).permitAll()
.and().authenticationManager(new ProviderManager(List.of(adAuthProvider, dbAuthProvider)));
return http.build();
}