StackOverflowError Trying to Expose Authentication

2019-05-24 12:39发布

问题:

I am attempting to create a Spring Security configuration by extending WebSecurityConfigurerAdapter basically like this:

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

}

And I'm seeing this:

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)
...

I've tried changing everything I can think of to properly get the AuthenticationManager exposed and not get a StackOverflow error and I'm still stuck. The only thing I've found is this defect, https://github.com/spring-projects/spring-security/issues/2732, with Spring Security where someone saw this same issue when there is "an invalid configuration that tries to expose the AuthenticationManager as a Bean when no authentication has been configured". Unfortunately I don't know what exactly that means or how to get around this.

This Spring Security config works in Spring XML config and this is my attempt to migrate to Spring Java Config. Is there a better way I should be configuring my Spring Security and/or exposing the AuthenticationManager to my custom authentication filter?

回答1:

I finally figured out the issue. The problem was that I overrode the wrong method. I did:

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

Instead of:

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

I ended up overriding a similar but incorrect method. The method authenticationManager() is used to do some configuration to the AuthenticationManager, authenticationManagerBean() is used to expose the AuthenticationManager as a Spring Bean that can be Autowired and used. Doing what I did causes the necessary configuration to not happen and instead links AuthenticationManagers in such a way that they cause a stack overflow.