Использование нескольких WebSecurityConfigurerAdapter с различными AuthenticationProviders (базовая аутентификация для API и LDAP для веб-приложения)
по Spring Security Reference section 5.7 должно быть возможно определить более одного адаптера безопасности.
Я пытаюсь сделать то же самое, но безуспешно. После перезагрузки сервера первый x раз API отлично работает с базовой аутентификацией, но через пару раз я перенаправлен на страницу входа (форма), это должно произойти только для нашего веб-приложения, а не для вызовов API.
мой код:
@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;
}
}
}
есть идеи?
Я использование Spring Boot версии 1.4.1-RELEASE и Spring Security версии 4.1.3-RELEASE.
1 ответов
вы используете то же самое AuthenticationManager
для обеих конфигураций, потому что вы autowire то же AuthenticationManagerBuilder
.
посмотреть Архитектура Безопасности Spring:
@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { ... // web stuff here @Autowired public initialize(AuthenticationManagerBuilder builder, DataSource dataSource) { auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
этот пример относится к веб-приложению, но использование
AuthenticationManagerBuilder
более широко применяется (см. ниже более подробную информацию о том, как реализуется безопасность веб-приложений). Обратите внимание, чтоAuthenticationManagerBuilder
is@Autowired
в метод@Bean
- это что заставляет его строить глобальный (Родительский) AuthenticationManager. Напротив, если бы мы сделали это так:@Configuration public class ApplicationSecurity extends WebSecurityConfigurerAdapter { @Autowired DataSource dataSource; ... // web stuff here @Override public configure(AuthenticationManagerBuilder builder) { auth.jdbcAuthentication().dataSource(dataSource).withUser("dave") .password("secret").roles("USER"); } }
(через
@Override
метода в конфигураторе), тоAuthenticationManagerBuilder
используется только для создания "локального"AuthenticationManager
, который является дочерним от глобального.