Reputation: 3374
After upgrading my project to Spring Boot 2.6.0
, I'm getting the following exception during startup:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'webSecurityConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.13.jar:5.3.13]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.13.jar:5.3.13]
However, my configuration seems to be in line with Spring documentation (HttpSecurity setup, AuthenticationManagerBuilder setup and PasswordEncoder setup):
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.mvcMatchers("/presentations")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("testuser")
.password(encoder().encode("password"))
.roles("READ");
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
Upvotes: 11
Views: 15021
Reputation: 1
I had taken your problem too. I solved this problem when I added 'spring.main.allow-circular-references=true'
into appplication.properties.xml
.
Using New Spring WebSecurtyConfig Above Version 2.7.0+
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws
Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and().httpBasic();
return http.build();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user")
.password(passwordEncoder().encode("password")).roles("USER");
}
@Bean
public PasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
If you want to use to AuthenticationManagerBuilder auth parameter in configureGlobal function, this method can add
'spring.main.allow-circular-references=true'
into appplication.properties.xml
.
OR, You can use this method
@Configuration
@EnableWebSecurity
@EnableMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends GlobalAuthenticationConfigurerAdapter {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.and().httpBasic();
return http.build();
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
}
}
Upvotes: 0
Reputation: 1
Change public PasswordEncoder encoder()
to static PasswordEncoder encoder()
Upvotes: -1
Reputation: 1477
I got the same error and able to resolve it by using overridden configure method instead of autowired configureGlobal.
Replaced this
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("testuser")
.password(encoder().encode("password"))
.roles("READ");
}
with this
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("testuser")
.password(encoder().encode("password"))
.roles("READ");
}
Upvotes: 2
Reputation: 3374
Having a closer look at my implementation, it seems the @Autowired
method calling the @Bean
PasswordEncoder
method is generating this issue (this doesn't happen if I call the method from within another @Bean
definition method).
The solution was then to move the logic to a different @Configuration
class:
@Configuration
public class UsersSetup {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth, PasswordEncoder encoder) throws Exception {
auth.inMemoryAuthentication()
.withUser("testuser")
.password(encoder.encode("password"))
.roles("READ");
}
}
The reason why this appeared with the new Boot version is because Boot now doesn't try to break the dependency cycle automatically by default any more:
As an alternative, I could also revert this feature to its former behavior by including the following application property in my project:
spring.main.allow-circular-references=true
Upvotes: 19