【发布时间】:2013-10-21 15:00:56
【问题描述】:
我在使用由@EnableGlobalMethodSecurity 控制的方法级别注释设置我的应用程序时遇到一些问题我正在使用 Servlet 3.0 样式初始化
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(MultiSecurityConfig.class);
}
}
我尝试了 2 种不同的方式来初始化 AuthenticationManager,它们都有自己的问题。请注意,不使用@EnableGlobalMethodSecurity 会导致服务器成功启动,并且所有表单安全性都按预期执行。当我在控制器上添加 @EnableGlobalMethodSecurity 和 @PreAuthorize("hasRole('ROLE_USER')") 注释时,我的问题就出现了。
我正在尝试独立设置基于表单和基于 api 的安全性。基于方法的注解只需要对 api 安全起作用。
一种配置如下。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**").httpBasic();
}
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
@Configuration
public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**","/status");
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER").and()
.formLogin().loginPage("/login").permitAll();
}
protected void registerAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
}
}
这并不理想,因为我真的只想要一个身份验证机制的注册,但主要问题是它会导致以下异常:
java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []
据我所知,@EnableGlobalMethodSecurity 设置了自己的AuthenticationManager,所以我不确定问题出在哪里。
第二种配置如下。
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {
@Bean
protected AuthenticationManager authenticationManager() throws Exception {
return new AuthenticationManagerBuilder(ObjectPostProcessor.QUIESCENT_POSTPROCESSOR)
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN").and()
.and()
.build();
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/api/**").httpBasic();
}
}
@Configuration
public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/static/**","/status");
}
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().hasRole("USER").and()
.formLogin().loginPage("/login").permitAll();
}
}
}
此配置实际上启动成功,但有一个异常
java.lang.IllegalArgumentException: A parent AuthenticationManager or a list of AuthenticationProviders is required
at org.springframework.security.authentication.ProviderManager.checkState(ProviderManager.java:117)
at org.springframework.security.authentication.ProviderManager.<init>(ProviderManager.java:106)
at org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder.performBuild(AuthenticationManagerBuilder.java:221)
当我测试时发现安全性不起作用。
我已经看了几天了,即使在深入研究 Spring Security 实现代码之后,我似乎也找不到我的配置有什么问题。
我正在使用 spring-security-3.2.0.RC1 和 spring-framework-3.2.3.RELEASE。
【问题讨论】:
-
你在哪里/如何加载这个
MultiSecurityConfig。这是由ContextLoaderListener加载的吗?如果是这样,安全将不起作用,因为您的Controllers由您的DispatcherServlet处理。
标签: java spring spring-mvc spring-security annotations