[JAVA] Addressing an issue that caused an AlreadyBuiltException in Spring Security

I was quite addicted to the problem that the application could not be started due to ʻAlreadyBuiltException` in Spring Security + Spring Boot, so the solution memo at that time.

Event

I omitted various things, but I created the following Java Config.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> auds;

    @Bean
    public PreAuthenticatedAuthenticationProvider preAuthenticationProvider() {
        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(auds);
        return provider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(preAuthenticationProvider()).build();
    }
}

If you start the application with such settings, the following error will occur.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.security.config.annotation.AlreadyBuiltException: This object has already been built

I got an error saying that springSecurityFilterChain has already been built, but it took me a while to determine the cause.

Cause

It was because I was running build with the configure method of the SecurityConfig class. It seems that when build is executed, ʻAuthenticationManager is generated, but in fact, it is executed by the parent class WebSecurityConfigurerAdapter`. It seems that such a problem has occurred because it was executed twice this time.

You can do the following.

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private AuthenticationUserDetailsService<PreAuthenticatedAuthenticationToken> auds;

    @Bean
    public PreAuthenticatedAuthenticationProvider preAuthenticationProvider() {
        PreAuthenticatedAuthenticationProvider provider = new PreAuthenticatedAuthenticationProvider();
        provider.setPreAuthenticatedUserDetailsService(auds);
        return provider;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(preAuthenticationProvider());
    }
}

In fact, even if you check the documentation etc., you haven't built it with JavaConfig. But it's a Builder class, and if the build method comes out as a complement, you'll want to build it!

You have to read the document properly. I wasted a lot of time.

Recommended Posts

Addressing an issue that caused an AlreadyBuiltException in Spring Security
Spring Security OAuth2 will end support in a few years, an alternative