Luk*_*uke 12 java spring annotations spring-mvc spring-security
我在使用方法级别注释设置我的应用程序时遇到了一些问题,@EnableGlobalMethodSecurity
我正在使用Servlet 3.0样式初始化
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(MultiSecurityConfig.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试了两种不同的方法来初始化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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这并不理想,因为我真的只想要一次注册认证机制,但主要问题是它会导致以下异常:
java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []
Run Code Online (Sandbox Code Playgroud)
据我所知@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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
此配置实际上已成功启动,但有例外
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)
Run Code Online (Sandbox Code Playgroud)
当我测试时,我发现安全性不起作用.
我已经看了几天了,甚至在深入了解Spring安全实现代码后,我似乎无法找到我的配置有什么问题.
我使用的是spring-security-3.2.0.RC1和spring-framework-3.2.3.RELEASE.
Rob*_*nch 13
当您使用protected registerAuthentication
方法上WebSecurityConfigurerAdapter
则作用域验证到WebSecurityConfigurerAdapter
如此EnableGlobalMethodSecurity
无法找到它.如果你考虑这个...它是有道理的,因为该方法是受保护的.
您看到的错误实际上是一个调试语句(注意级别是DEBUG).原因是Spring Security将尝试使用几种不同的方法来自动连接全局方法安全性.具体EnableGlobalMethodSecurity
将尝试以下方式尝试获取AuthenticationManager
:
GlobalMethodSecurityConfiguration
和覆盖registerAuthentication
它将使用AuthenticationManagerBuilder
传入的.这允许隔离,AuthenticationManager
就像你可以使用相同的方式隔离WebSecurityConfigurerAdapter
AuthenticationManagerBuilder
,如果失败则记录您看到的错误消息(注意日志还说明"现在可以,我们将尝试直接使用AuthenticationManager")AuthenticationManager
暴露为bean的方法.对于您的代码,您最好使用以下内容:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class MultiSecurityConfig {
// Since MultiSecurityConfig does not extend GlobalMethodSecurityConfiguration and
// define an AuthenticationManager, it will try using the globally defined
// AuthenticationManagerBuilder to create one
// The @Enable*Security annotations create a global AuthenticationManagerBuilder
// that can optionally be used for creating an AuthenticationManager that is shared
// The key to using it is to use the @Autowired annotation
@Autowired
public void registerSharedAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
// Since we didn't specify an AuthenticationManager for this class,
// the global instance is used
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.httpBasic();
}
}
@Configuration
public static class FormWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
// Since we didn't specify an AuthenticationManager for this class,
// the global instance is used
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:有关此内容的更多文档将在未来几天内添加到参考中.
归档时间: |
|
查看次数: |
22148 次 |
最近记录: |