StackOverflowError 试图在 Spring WebSecurity 中公开 AuthenticationManagerConfigurerAdapter

我正在尝试通过扩展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)
...

我已经尝试更改了我能想到的所有内容,以正确公开身份验证管理器,而不会出现StackOverflow错误,但我仍然卡住了。我唯一发现的是这个缺陷,https://github.com/spring-projects/spring-security/issues/2732,在Spring Security中,当存在“一个无效的配置,当没有配置身份验证时,有人看到了同样的问题,试图将SacistionManager公开为Bean”。不幸的是,我不知道这到底是什么意思,也不知道如何解决这个问题。

这个Spring Security配置在Spring XML配置中工作,这是我迁移到Spring Java Config的尝试。有没有更好的方法来配置我的Spring安全性和/或向我的自定义身份验证过滤器公开身份验证管理器?


答案 1

我终于弄清楚了这个问题。问题是我推翻了错误的方法。我做了:

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

而不是:

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

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


答案 2

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

@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);
}

推荐