Description
Hi,
there seems to be a strange behavior, when there is a Security Configuration which exposes AuthenticationProvider
s as Spring @Bean
s, which use HttpSecurity
as a method argument. The application does not start due to circular references, depending on which Spring Security Version is in use:
Spring Boot 3.2.7, Spring Security 6.2.5:
If there is only one AuthenticationProvider
there is a circular reference:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
// Security configuration omitted (it doesn't matter)
// Triggers a circular reference, when only one AuthenticationProvider bean is present
@Bean
public AnonymousAuthenticationProvider anonymousAuthenticationProviderOne(@Nonnull HttpSecurity http) throws Exception {
return new AnonymousAuthenticationProvider("helloWorld1");
}
}
Exception:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration (field private org.springframework.security.config.annotation.web.builders.HttpSecurity org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.httpSecurity)
┌─────┐
| org.springframework.security.config.annotation.web.configuration.HttpSecurityConfiguration.httpSecurity defined in class path resource [org/springframework/security/config/annotation/web/configuration/HttpSecurityConfiguration.class]
↑ ↓
| anonymousAuthenticationProviderOne defined in class path resource [org/example/SecurityConfiguration.class]
└─────┘
If there is more than one AuthenticationProvider
, everything is fine:
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
// Security configuration omitted (it doesn't matter)
// No circular reference is triggered, when two AuthenticationProvider beans are present
@Bean
public AnonymousAuthenticationProvider anonymousAuthenticationProviderOne(@Nonnull HttpSecurity http) throws Exception {
return new AnonymousAuthenticationProvider("helloWorld1");
}
@Bean
public AnonymousAuthenticationProvider anonymousAuthenticationProviderTwo(@Nonnull HttpSecurity http) throws Exception {
return new AnonymousAuthenticationProvider("helloWorld2");
}
}
Spring Boot 3.3.5, Spring Security 6.3.4:
In this setup, it doesn't matter if there is only one AuthenticationProvider
bean or two AuthenticationProvider
beans. The application does not start in both cases due to circular references.
Analysis
I traced the cause to the InitializeAuthenticationProviderManagerConfigurer
, which tries to default an AuthenticationProvider
in the AuthenticationManagerBuilder
, when there is exactly one AuthenticationProvider
present. In version 6.2.5 the circular reference is triggered when the configurer tries to resolve the one Authentication bean. In version 6.3.4, the circular reference is triggered earlier.
Expected behavior
Correct me if I'm wrong, i found similar issues regarding circular references, but I think this is something new. Is the method signature AuthenticationProvider
as @Bean
with a dependency to HttpSecurity
a bad practise? Is it a bad idea to expose an AuthenticationProvider
at all? If the method argument HttpSecurity
is removed, everything seems to work fine. The method argument HttpSecurity
is primarily used to allow access to shared objects and to maintain a consistent method signature. I can provide a full example if necessary.