I have a requirement of multiple security configurations in a Spring Boot 3.0 application where postman API calls need to do oauth and application authentication would be through LdapWebSecurityConfigurerAdapter
. I have this existing code which has ldap
and oauth2
security configuration. I have migrated oauth2
to sping authorization server
. My changes for spring authorization server & ldap work fine individually by commenting the other class. However, spring authorization server login gives 401 when /oauth2/authorize endpoint is hit. Following are my configurations.
Spring Authorization server config having InMemoryRegisteredClientRepository:
@Bean
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
logger.info("Inside authorizationServerSecurityFilterChain");
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults());
http.exceptionHandling(e -> e
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")))
.oauth2ResourceServer((oauth2) -> oauth2.jwt(customizer -> customizer.jwtAuthenticationConverter(jwtAuthenticationConverter())));
return http.build();
}
Spring DefaultSecurityFilterChain :
@Bean
@Order(2)
SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
logger.info("Inside defaultSecurityFilterChain");
http
.authorizeHttpRequests(authorizeRequests ->
authorizeRequests
.requestMatchers("/oauth2/**").permitAll()
.requestMatchers("/login").permitAll()
.requestMatchers("/api/**").authenticated()
).oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()))
.formLogin(Customizer.withDefaults());
return http.build();
LDAP configuration :
public static class LdapWebSecurityConfigurerAdapter{
// DEPENDENCY INJECTIONS HERE
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
// LdapAuthenticationProviderConfigurer CONFIGURATION HERE
}
@Bean
@Order(3)
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
log.info("Inside filterChain");
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers("/app/**")
)
.exceptionHandling((exceptionHandling) ->
exceptionHandling.authenticationEntryPoint(authenticationEntryPoint))
.formLogin(formLogin -> formLogin.loginProcessingUrl("/app/authentication")
.successHandler(ajaxAuthenticationSuccessHandler)
.failureHandler(ajaxAuthenticationFailureHandler)
.usernameParameter("j_username")
.passwordParameter("j_password")
.permitAll())
.logout((logout) -> logout.logoutUrl("/app/logout")
.logoutSuccessHandler(ajaxLogoutSuccessHandler)
.deleteCookies("JSESSIONID")
.permitAll())
.csrf((csrf) -> csrf.disable())
.headers((headers) -> headers.frameOptions(Customizer.withDefaults()).disable());
http.authorizeHttpRequests((authorizeHttpRequests) ->
authorizeHttpRequests
.requestMatchers("/app/rest/register").permitAll()
.requestMatchers("/app/rest/activate").permitAll()
.requestMatchers("/app/rest/authenticate").permitAll()
.requestMatchers("/app/rest/logs/**").hasAuthority(AuthoritiesConstants.ADMIN)
.requestMatchers("/app/**").permitAll()
.requestMatchers("/app/**").authenticated());
return http.build();
}
}
So, for this setup if I comment the LdapWebSecurityConfigurerAdapter, the authorization server works fine, however, It does not work when un-commented. The /oauth2/authorize/
endpoint call is redirected to /login
for authorization server login, but the page does not render due to 401 error. I tried explicitly permitting the /oauth2/**
and /login
calls, but it does not work. Do I need to do anymore settings for login page to render and proceed the authentication with oauth2? Any help would be much appreciated.
So, for this setup if I comment the LdapWebSecurityConfigurerAdapter, the authorization server works fine, however, It does not work when un-commented. The /oauth2/authorize/
endpoint call is redirected to /login
for authorization server login, but the page does not render due to 401 error.
- I tried explicitly permitting the
/oauth2/**
and/login
calls, but it does not work. - I tried combining
defaultSecurityFilterChain
withconfigure()
method ofLdapWebSecurityConfigurerAdapter
but it does not work.
Do I need to do anymore settings for login page to render and proceed the authentication with oauth2? Or how can I segregate the two authentication flows. Any help would be much appreciated!
At a glance, it looks like your
@Order(3)
filterChain
will never be hit, because the earlierdefaultSecurityFilterChain
has an implicitanyRequest().denyAll()
rule.A lot of the rest of your configuration seems experimental so I can't tell what you're intended working configuration would be. However, it seems you should just need two filter chains, and the 2nd filter chain should be configured to use LDAP. In other words, you should go back to the filter chains defined in the Getting Started example and add the minimum required config to support LDAP, which would be defining a custom
AuthenticationManager
as a@Bean
and that should be it.If you also need to support API calls via postman, see this answer for how to correctly add another filter chain for those API calls. Note that in that case, you can wire a custom
AuthenticationManager
into the filter chain usingformLogin()
(which would end up being the 3rd filter chain) viahttp.authenticationManager(...)
. You don't need publish it as a@Bean
when using theauthenticationManager()
DSL method.