Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)
You use the same AuthenticationManager
for both configurations, because you autowire the same AuthenticationManagerBuilder
.
See Spring Security Architecture:
@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { ... // web stuff here @Autowired public void initialize(AuthenticationManagerBuilder builder, DataSource dataSource) { builder.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
This example relates to a web application, but the usage of
AuthenticationManagerBuilder
is more widely applicable (see below for more detail on how web application security is implemented). Note that theAuthenticationManagerBuilder
is@Autowired
into a method in a@Bean
- that is what makes it build the global (parent) AuthenticationManager. In contrast if we had done it this way:@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { @Autowired DataSource dataSource; ... // web stuff here @Override public void configure(AuthenticationManagerBuilder builder) { builder.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
(using an
@Override
of a method in the configurer) then theAuthenticationManagerBuilder
is only used to build a "local"AuthenticationManager
, which is a child of the global one.
Dimi
Updated on June 03, 2022Comments
-
Dimi almost 2 years
According the Spring Security Reference section 5.7 it should be possible to define more than one security adapter.
I try to do the same but without success. After a server reboot, the first x times the API works fine with basic auth, but after a couple of times I'm redirected to the login (form) page, this should only happen for our web app, not for the API calls.
My code:
@EnableWebSecurity public class MultiHttpSecurityConfig { @Configuration @Order(1) public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Autowired private Environment env; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication(). withUser("admin").password("pw_test").roles(API_ROLE); } protected void configure(HttpSecurity http) throws Exception { http .antMatcher("/services/**") .authorizeRequests() .anyRequest().hasRole(API_ROLE) .and() .httpBasic() .and() .csrf() .disable(); } } @Configuration @Order(2) public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { @Autowired private Environment env; @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(activeDirectoryLdapAuthenticationProvider()); auth.eraseCredentials(false); } @Override protected void configure(HttpSecurity http) throws Exception { // LDAP FORM AUTHENTICATION http.authorizeRequests() .antMatchers("/login.html").permitAll() .antMatchers("/css/**").permitAll() .antMatchers("/js/**").permitAll() .antMatchers("/images/**").permitAll() .anyRequest().authenticated() .and().formLogin() .failureUrl("/login.html?error=1") .loginPage("/login.html") .loginProcessingUrl("/j_spring_security_check") .defaultSuccessUrl("/success.html") .usernameParameter("j_username") .passwordParameter("j_password") .permitAll(); http.csrf().disable(); // iFRAMES SETTINGS http .headers() .frameOptions().sameOrigin() .httpStrictTransportSecurity().disable(); // HTTPS http .requiresChannel() .anyRequest() .requiresSecure(); //MAP 8080 to HTTPS PORT http.portMapper().http(8080).mapsTo(443); } @Bean public AuthenticationProvider activeDirectoryLdapAuthenticationProvider() { CustomLdapAuthenticationProvider provider = new CustomLdapAuthenticationProvider(env.getProperty("ldap.domain"), env.getProperty("ldap.url"), env.getProperty("ldap.base")); provider.setConvertSubErrorCodesToExceptions(true); provider.setUseAuthenticationRequestCredentials(true); return provider; } } }
Any idea?
I'm using Spring Boot version 1.4.1-RELEASE and Spring Security version 4.1.3-RELEASE.