StackOverflowError试图在Spring WebSecurityConfigurerAdapter中公开AuthenticationManager

时间:2017-03-11 00:39:59

标签: java spring spring-security filter spring-java-config

我试图通过扩展WebSecurityConfigurerAdapter来创建Spring Security配置,基本上是这样的:

@EnableWebSecurity
@Configuration
public class StackOverflowSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.authenticationProvider(myUsernamePasswordProvider());
        auth.authenticationProvider(mySecurityTokenProvider());

        super.configure(auth);
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public MyPreAuthenticatedProcessingFilter myAuthenticationFilter() throws Exception {
        MyPreAuthenticatedProcessingFilter myAuthenticationFilter = new MyPreAuthenticatedProcessingFilter();
        myAuthenticationFilter.setAuthenticationManager(authenticationManager());

        return myAuthenticationFilter;
    }

}

我看到了这个:

SEVERE: Servlet.service() for servlet [servlet] in context with path [/MyApp] threw exception [Filter execution threw an exception] with root cause
[INFO] [talledLocalContainer] java.lang.StackOverflowError
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.AnonymousAuthenticationProvider.supports(AnonymousAuthenticationProvider.java:79)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:164)
[INFO] [talledLocalContainer]   at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:469)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
[INFO] [talledLocalContainer]   at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:469)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
[INFO] [talledLocalContainer]   at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:469)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
[INFO] [talledLocalContainer]   at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:469)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
[INFO] [talledLocalContainer]   at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter$AuthenticationManagerDelegator.authenticate(WebSecurityConfigurerAdapter.java:469)
[INFO] [talledLocalContainer]   at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199)
...

我已经尝试更改我能想到的所有内容以正确获取AuthenticationManager并且没有得到StackOverflow错误而且我仍然卡住了。我发现的唯一问题就是这个缺陷,https://github.com/spring-projects/spring-security/issues/2732,在Spring Security中,当有“无法配置试图在没有配置认证时将AuthenticationManager公开为Bean”时,有人看到了同样的问题。不幸的是,我不知道究竟是什么意思或如何解决这个问题。

这个Spring Security配置适用于Spring XML配置,这是我尝试迁移到Spring Java Config。有没有更好的方法来配置我的Spring Security和/或将AuthenticationManager公开给我的自定义身份验证过滤器?

2 个答案:

答案 0 :(得分:7)

我终于弄明白了这个问题。问题是我覆盖了错误的方法。我做了:

@Override
@Bean
public AuthenticationManager authenticationManager() throws Exception {
    return super.authenticationManagerBean();
}

而不是:

@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

我最终覆盖了一个类似但不正确的方法。方法authenticationManager()用于对AuthenticationManager进行一些配置,authenticationManagerBean()用于将AuthenticationManager公开为可以自动装配和使用的Spring Bean。执行我所做的操作会导致必要的配置不会发生,而是以一种导致堆栈溢出的方式链接AuthenticationManagers。

答案 1 :(得分:1)

当您使用相同实例配置父身份验证提供程序时,也可能发生此(相似的症状)问题。即:

@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
            // next line can cause same stack overflow in case of non-existent user tries login.
            //.parentAuthenticationManager(authenticationManagerBean())
            .userDetailsService(customUserDetailsService)
            .passwordEncoder(passwordEncoder())
            .userDetailsPasswordManager(customUserDetailsService);
    super.configure(auth);
}