はじめに
Spring Securityで謎のStackOverFlowが発生し、どうにか解決できたので今後のその対応方法をメモしておく。
環境
- Java : 1.8.0 Update 45
- Spring Framework : 4.2.0.RELEASE
- Spring Security : 4.0.2.RELEASE
- Tomcat : 8.0.23
現象
以下のような実装をしたところ、Tomcat起動後にトップページにアクセスするだけで、StackOverFlowが発生。
処理が循環しているっぽかった。
実装
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.anonymous()
.and()
.formLogin().loginPage("/login")
.and()
.logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.invalidateHttpSession(true)
.logoutSuccessUrl("/login")
.and()
.exceptionHandling().accessDeniedHandler(accessDeniedHandler())
.and()
.csrf()
.and()
.requestMatcher(securityRequestMatcher());
}
・
・
・
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
SystemWideSaltSource saltSource = new SystemWideSaltSource();
saltSource.setSystemWideSalt("system");
ShaPasswordEncoder shaPasswordEncoder = new ShaPasswordEncoder(256);
shaPasswordEncoder.setEncodeHashAsBase64(true);
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setSaltSource(saltSource);
provider.setUserDetailsService(userDetailsService());
provider.setPasswordEncoder(shaPasswordEncoder);
auth.authenticationProvider(provider);
}
@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManagerBean();
}
・
・
・
}
ログ
12-Aug-2015 17:16:28.013 SEVERE [http-nio-8080-exec-3] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [/] threw exception [フィルタの実行により例外を投げました] with root cause
java.lang.StackOverflowError
at org.apache.commons.logging.impl.SLF4JLocationAwareLog.isDebugEnabled(SLF4JLocationAwareLog.java:67)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:154)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:446)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:192)
対応
super.authenticationManagerBean()
を super.authenticationManager()
とした。
@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
今後
Spring Securityの実装をもう少し詳細に見てみて、使い方が悪いのかSpringがおかしいのか見極める予定。