Problem
Recently while I was working with Spring Security in recent versions of Spring Boot framework (2.6.6/2.6.7), I was getting the following error (Requested bean is currently in creation: Is there an unresolvable circular reference?):
o.s.boot.SpringApplication : Application run failed
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'securityConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
The class SecurityConfig (hence the bean name inferred as securityConfig) extends WebSecurityConfigurerAdapter class. This (SecurityConfig) is a configuration class using @Configuration
& @EnableWebSecurity
annotations.
The SecurityConfig class is given below:
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder()).withUser("user")
.password("$2a$10$9Xn39aPf4LhDpRGNWvDFqu.T5ZPHbyh8iNQDSb4aNSnLqE2u2efIu").roles("USER").and()
.passwordEncoder(passwordEncoder()).withUser("admin")
.password("$2a$10$dl8TemMlPH7Z/mpBurCX8O4lu0FoWbXnhsHTYXVsmgXyzagn..8rK").roles("USER", "ADMIN");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Solutions
Not exactly known what was the issue, but here are some solutions that worked for me.
Override configure() Method
I replaced the following code:
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
...
}
by
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
...
}
So basically instead of auto-wiring the method I have overridden the method configure()
from the super class WebSecurityConfigurerAdapter.
Move PasswordEncoder in Separate Class
Another solution is moving the passwordEncoder()
method into a separate class for creating PasswordEncoder instance. In this case, you don’t need to override the method configure()
from parent class WebSecurityConfigurerAdapter.
Create a similar class for the PasswordEncoder bean as given below:
@Configuration
public class EncoderConfig {
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
Now you can use the password encode in the following manner:
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
public void registerGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().passwordEncoder(passwordEncoder).withUser("user")
.password("$2a$10$9Xn39aPf4LhDpRGNWvDFqu.T5ZPHbyh8iNQDSb4aNSnLqE2u2efIu").roles("USER").and()
.passwordEncoder(passwordEncoder).withUser("admin")
.password("$2a$10$dl8TemMlPH7Z/mpBurCX8O4lu0FoWbXnhsHTYXVsmgXyzagn..8rK").roles("USER", "ADMIN");
}
}
Sample Code
You can download the sample code used in this example.