I have user details maintained in different internal_users and external_users DB tables. For that I am creating two different authentication providers, for various flow of authentication. Below is the code that is giving error:
@Configuration
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
private internalUserDetailsServiceImpl internalUserDetailsService;
@Autowired
private externalUserDetailsServiceImpl externalUserDetailsServiceImpl;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Autowired
private PasswordEncoder passwordEncoder;
private static final String[] AUTH_WHITELIST = {
"/api/auth/**",
"/swagger-resources/**",
"/swagger-ui/**",
"/v3/api-docs",
"/v2/api-docs",
"/webjars/**"
};
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
@Bean
public DaoAuthenticationProvider externalUserauthenticationProvider() {
DaoAuthenticationProvider externalUserAuthProvider = new DaoAuthenticationProvider();
externalUserAuthProvider.setUserDetailsService(externalUserDetailsServiceImpl);
externalUserAuthProvider.setPasswordEncoder(passwordEncoder);
return externalUserAuthProvider;
}
@Bean
public DaoAuthenticationProvider internalUserAuthenticationProvider() {
DaoAuthenticationProvider internalUserAuthProvider = new DaoAuthenticationProvider();
internalUserAuthProvider.setUserDetailsService(internalUserDetailsServiceImpl);
internalUserAuthProvider.setPasswordEncoder(passwordEncoder);
return internalUserAuthProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.authenticationProvider(internalUserAuthProvider())
.authenticationProvider(externalUserAuthProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
I am getting below issue:
Handler dispatch failed; nested exception is java.lang.StackOverflowError
On further debugging I found that the controller, where below code is used, authenticationManager
is showing an error as shown in image attached
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authDTO.getUserName(), authDTO.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
On commenting out any one of the authentication providers, the code is working, but not working with both authentication providers. Below is working code with one authentication provider
@Configuration
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig {
@Autowired
private internalUserDetailsServiceImpl internalUserDetailsService;
@Autowired
private externalUserDetailsServiceImpl externalUserDetailsServiceImpl;
@Autowired
private AuthEntryPointJwt unauthorizedHandler;
@Autowired
private PasswordEncoder passwordEncoder;
private static final String[] AUTH_WHITELIST = {
"/api/auth/**",
"/swagger-resources/**",
"/swagger-ui/**",
"/v3/api-docs",
"/v2/api-docs",
"/webjars/**"
};
@Bean
public AuthTokenFilter authenticationJwtTokenFilter() {
return new AuthTokenFilter();
}
@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception {
return authConfig.getAuthenticationManager();
}
/*@Bean
public DaoAuthenticationProvider externalUserauthenticationProvider() {
DaoAuthenticationProvider externalUserAuthProvider = new DaoAuthenticationProvider();
externalUserAuthProvider.setUserDetailsService(externalUserDetailsServiceImpl);
externalUserAuthProvider.setPasswordEncoder(passwordEncoder);
return externalUserAuthProvider;
} */
@Bean
public DaoAuthenticationProvider internalUserAuthenticationProvider() {
DaoAuthenticationProvider internalUserAuthProvider = new DaoAuthenticationProvider();
internalUserAuthProvider.setUserDetailsService(internalUserDetailsServiceImpl);
internalUserAuthProvider.setPasswordEncoder(passwordEncoder);
return internalUserAuthProvider;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.authorizeRequests().antMatchers(AUTH_WHITELIST).permitAll()
.antMatchers("/api/test/**").permitAll()
.anyRequest().authenticated();
http.authenticationProvider(internalUserAuthProvider());
//.authenticationProvider(externalUserAuthProvider());
http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Any clue what exactly I am missing.
I found the solution in this thread stackoverflow.com/questions/73322338/…
why are you using a JWT as a session, there is no such implementation because its insecure to do so, and you just dont care and write a custom jwtfilter