使用具有不同AuthenticationProviders的多个WebSecurityConfigurerAdapter(用于Web应用程序的API和LDAP的基本身份验证) [英] Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)
问题描述
根据 Spring Security Reference section 5.7 应该可以定义多个安全适配器。
According the Spring Security Reference section 5.7 it should be possible to define more than one security adapter.
我尝试做同样但没有成功。在服务器重新启动之后,API的前x次正常使用基本身份验证,但是经过几次我被重定向到登录(表单)页面,这应该只针对我们的Web应用程序,而不是API调用。
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.
我的代码:
@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。
I'm using Spring Boot version 1.4.1-RELEASE and Spring Security version 4.1.3-RELEASE.
推荐答案
你使用相同的 AuthenticationManager
,因为您自动装配相同的 AuthenticationManagerBuilder
。
You use the same AuthenticationManager
for both configurations, because you autowire the same AuthenticationManagerBuilder
.
请参阅 Spring Security Architecture :
@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");
}
}
此示例与Web应用程序有关,但 AuthenticationManagerBuilder
的使用更为广泛适用(有关如何实施Web应用程序安全性的更多详细信息,请参阅下文)。请注意, AuthenticationManagerBuilder
是 @Autowired
到 @Bean $ c中的方法$ c> - 这就是它构建全局(父)AuthenticationManager的原因。相反,如果我们这样做:
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 the AuthenticationManagerBuilder
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 configure(AuthenticationManagerBuilder builder) {
auth.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
(使用配置器中方法的@Override
然后 AuthenticationManagerBuilder
仅用于构建本地 AuthenticationManager
,这是全球的孩子。
(using an @Override
of a method in the configurer) then the AuthenticationManagerBuilder
is only used to build a "local" AuthenticationManager
, which is a child of the global one.
这篇关于使用具有不同AuthenticationProviders的多个WebSecurityConfigurerAdapter(用于Web应用程序的API和LDAP的基本身份验证)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!