java 使用具有不同 AuthenticationProviders 的多个 WebSecurityConfigurerAdapter(API 的基本身份验证和 Web 应用程序的 LDAP)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40258583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app)
提问by Dimi
According the Spring Security Reference section 5.7it should be possible to define more than one security adapter.
根据Spring Security Reference 5.7 节,应该可以定义多个安全适配器。
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.
我尝试做同样的事情,但没有成功。服务器重新启动后,前 x 次 API 可以正常使用基本身份验证,但几次后我被重定向到登录(表单)页面,这应该只发生在我们的 Web 应用程序中,而不是 API 调用中。
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.
我使用的是 Spring Boot 版本 1.4.1-RELEASE 和 Spring Security 版本 4.1.3-RELEASE。
采纳答案by dur
You use the same AuthenticationManager
for both configurations, because you autowire the same AuthenticationManagerBuilder
.
您AuthenticationManager
对两种配置使用相同的配置,因为您自动装配相同的AuthenticationManagerBuilder
.
See Spring Security Architecture:
请参阅Spring 安全架构:
@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.
@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"); } }
此示例与 Web 应用程序相关,但其使用范围
AuthenticationManagerBuilder
更广(有关如何实现 Web 应用程序安全性的更多详细信息,请参见下文)。请注意,AuthenticationManagerBuilder
is@Autowired
into a 中的方法@Bean
- 这就是它构建全局(父)AuthenticationManager 的原因。相反,如果我们这样做:@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"); } }
(
@Override
在配置器中使用of a 方法)那么 theAuthenticationManagerBuilder
仅用于构建一个“local”AuthenticationManager
,它是全局一个的子级。