_@EnableGlobalMethodSecurity
_によって制御されるメソッドレベルのアノテーションを使用してアプリケーションをセットアップする際に問題が発生します。サーブレット3.0スタイルの初期化を使用しています。
_public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(MultiSecurityConfig.class);
}
}
_
AuthenticationManager
を初期化する2つの異なる方法を、両方とも独自の問題で試みました。 not _@EnableGlobalMethodSecurity
_を使用すると、サーバーが正常に起動し、すべてのフォームセキュリティが期待どおりに実行されることに注意してください。コントローラに_@EnableGlobalMethodSecurity
_および@PreAuthorize("hasRole('ROLE_USER')")
アノテーションを追加すると、問題が発生します。
フォームベースとAPIベースのセキュリティを個別に設定しようとしています。メソッドベースのアノテーションは、APIセキュリティでのみ機能する必要があります。
1つの構成は次のとおりです。
_@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");
}
}
}
_
認証メカニズムの登録は1つだけにしたいので、これは理想的ではありませんが、主な問題は、次の例外が発生することです。
_Java.lang.IllegalArgumentException: Expecting to only find a single bean for type interface org.springframework.security.authentication.AuthenticationManager, but found []
_
私の知る限り、_@EnableGlobalMethodSecurity
_は独自のAuthenticationManager
を設定しているので、ここで何が問題なのかわかりません。
2番目の構成は次のとおりです。
_@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-3.2.0.RC1とspring-framework-3.2.3.RELEASEを使用しています。
WebSecurityConfigurerAdapter
でprotected registerAuthentication
メソッドを使用すると、認証がそのWebSecurityConfigurerAdapter
にスコープされるため、EnableGlobalMethodSecurity
はそれを見つけることができません。あなたがこれについて考えるならば...メソッドが保護されているのでそれは理にかなっています。
表示されているエラーは、実際にはデバッグステートメントです(レベルがDEBUGであることに注意してください)。その理由は、SpringSecurityがグローバルメソッドセキュリティを自動的に配線するためにいくつかの異なる方法を試みるためです。具体的には、EnableGlobalMethodSecurity
は次の方法でAuthenticationManager
を取得しようとします。
GlobalMethodSecurityConfiguration
を拡張してregisterAuthentication
をオーバーライドすると、渡されたAuthenticationManagerBuilder
が使用されます。これにより、AuthenticationManager
を同じ方法で分離できます。 WebSecurityConfigurerAdapter
でそうしますAuthenticationManagerBuilder
のグローバル共有インスタンスからビルドしてみてください。失敗した場合は、表示されているエラーメッセージがログに記録されます(ログには「今のところ問題ありません。AuthenticationManagerを直接使用してみます」と記載されていることに注意してください)。AuthenticationManager
を使用してみてください。コードには、次のようなものを使用するのが最善です。
@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();
}
}
}
注:これに関するドキュメントは、数日中にリファレンスに追加される予定です。