不久前我有一個有趣的情況,它在Spring Security的AuthenticationManager
中導致了一個無限循環(並最終導致堆棧溢出)。幾個月來,一切都按預期工作,但後來我決定將我的XML配置轉換爲純代碼配置。這是我在Java配置基本設置:在Spring Security 3.2.5中,在AuthenticationManager實現內部導致無限循環的是什麼?
@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.my.company" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// Disable default configuration
public SecurityConfig() {
super(true);
}
@Autowired
AuthenticationProviderImpl authenticationProvider;
@Autowired
MyAuthenticationEntryPoint customAuthenticationEntryPoint;
@Autowired
AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter;
@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) throws Exception {
// Ignore requests of resources in security
web.ignoring().antMatchers("/resources/**")
// Ignore requests to authentication
.and().ignoring().antMatchers("/auth/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// Define main authentication filter
http.addFilterBefore(authenticationTokenProcessingFilter,
UsernamePasswordAuthenticationFilter.class)
// Request path authorization
.authorizeRequests()
.antMatchers("/api/**")
.access("isAuthenticated()")
// Authentication provider
.and()
.authenticationProvider(authenticationProvider)
// Security failure exception handling
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
// Session Management
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// Default security HTTP headers
.and().headers().xssProtection().frameOptions()
.cacheControl().contentTypeOptions();
}
}
不過,我很快就發現了這個配置出現問題的原因我AuthenticationProviderImpl
(它實現了Spring Security的AuthenticationProvider
接口)。當實現的重寫authenticate
方法拋出BadCredentialsException
時,該類中完全相同的方法將被永久調用,直到堆棧溢出。好消息是,我通過簡單覆蓋configure(AuthenticationManagerBuilder builder)
中的SecurityConfig
並聲明我在那裏實現了AuthenticationProvider
而不是在configure(HttpSecurity http)
中修復了我的配置。這裏是固定的版本:
@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackages = { "com.my.company" })
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// Disable default configuration
public SecurityConfig() {
super(true);
}
@Autowired
AuthenticationProviderImpl authenticationProvider;
@Autowired
MyAuthenticationEntryPoint customAuthenticationEntryPoint;
@Autowired
AuthenticationTokenProcessingFilter authenticationTokenProcessingFilter;
@Bean(name = "authenticationManager")
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(AuthenticationManagerBuilder builder) {
// Configure the authentication manager WITH the authentication
// provider. Not overriding this method causes very bad things to
// happen.
builder.authenticationProvider(authenticationProvider);
}
@Override
public void configure(WebSecurity web) throws Exception {
// Ignore requests of resources in security
web.ignoring().antMatchers("/resources/**")
// Ignore requests to authentication
.and().ignoring().antMatchers("/auth/**");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// Define main authentication filter
http.addFilterBefore(authenticationTokenProcessingFilter,
UsernamePasswordAuthenticationFilter.class)
// Request path authorization
.authorizeRequests()
.antMatchers("/api/**")
.access("isAuthenticated()")
.and()
// Security failure exception handling
.exceptionHandling()
.authenticationEntryPoint(customAuthenticationEntryPoint)
// Session Management
.and().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
// Default security HTTP headers
.and().headers().xssProtection().frameOptions()
.cacheControl().contentTypeOptions();
}
}
雖然我相信我的問題就解決了與固定的配置,我仍然不知道爲什麼申請被無限調用authenticate()
異常時由我實施AuthenticationProvider
拋出?我嘗試了一下並檢查Spring Security類,但是我沒有找到合適的答案。感謝您的專業知識!
有人猜測,我會說你的班級沒有正確地將控制權傳遞給過濾器鏈中的下一個鏈接。我強調這只是純粹的猜測,但如果啓用Spring Security的調試模式,您可以深入瞭解發生了什麼。 – JamesENL 2015-02-24 02:00:54
有趣。日誌記錄並沒有顯示太多,除了這種模式在第一次迭代後重復:'2015-02-24 11:15:27 DEBUG - 返回單身bean'authenticationManager'的緩存實例 2015-02-24 11:15 :27 DEBUG - 使用com.my.company.service.AuthenticationProviderImpl進行身份驗證的嘗試 – Dustin 2015-02-24 16:22:27