使用具有不同 AuthenticationProviders 的多个 WebSecurityConfigurerAdapter(API 的基本身份验证和 Web 应用的 LDAP)
Posted
技术标签:
【中文标题】使用具有不同 AuthenticationProviders 的多个 WebSecurityConfigurerAdapter(API 的基本身份验证和 Web 应用的 LDAP)【英文标题】:Using multiple WebSecurityConfigurerAdapter with different AuthenticationProviders (basic auth for API and LDAP for web app) 【发布时间】:2017-03-08 14:26:21 【问题描述】:根据Spring Security Reference section 5.7,应该可以定义多个安全适配器。
我尝试做同样的事情,但没有成功。服务器重新启动后,API 的前 x 次使用基本身份验证正常工作,但几次后我被重定向到登录(表单)页面,这应该只发生在我们的 Web 应用程序,而不是 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
,因为您自动连接相同的AuthenticationManagerBuilder
。
见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");
此示例与 Web 应用程序有关,但
AuthenticationManagerBuilder
的使用更广泛(有关如何实现 Web 应用程序安全性的更多详细信息,请参见下文)。请注意,AuthenticationManagerBuilder
是@Autowired
中的一个方法@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
方法)然后AuthenticationManagerBuilder
仅用于构建“本地”AuthenticationManager
,它是全局的子代。
【讨论】:
以上是关于使用具有不同 AuthenticationProviders 的多个 WebSecurityConfigurerAdapter(API 的基本身份验证和 Web 应用的 LDAP)的主要内容,如果未能解决你的问题,请参考以下文章
使用具有不同模型和 DataTemplates 的分组 ListView