Issue
I am unable to update my spring boot app to 2.6.0 from 2.5.7. It throws the following error.
2021-12-07T08:40:22,311 ERROR [restartedMain] o.s.b.SpringApplication.reportFailure:819|| Application run failed org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'webSecurityConfig':
The requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227)
From the spring-boot 2.6.0 release notes, it is clear that circular references are disabled. And it can be enabled back with the property spring.main.allow-circular-references = true
. But I would like to fix the circular reference in the first place. Can anyone help me troubleshoot this issue? Please find the WebSecurityConfig class below,
@Configuration
@EnableWebSecurity
@SuppressWarnings({"PMD.SignatureDeclareThrowsException"})
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsService userDetailsService;
public WebSecurityConfig(final UserDetailsService userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Bean
public BCryptPasswordEncoder bcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/registration", "/css/**", "/js/**", "/h2-console/*").permitAll()
.anyRequest().authenticated().and()
.formLogin()
.loginPage("/login").permitAll().and()
.headers()
.frameOptions().sameOrigin().and()
.logout()
.permitAll().and()
.requiresChannel()
.requestMatchers(r -> r.getHeader("X-Forwarded-Proto") != null)
.requiresSecure();
}
@Autowired
public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bcryptPasswordEncoder());
}
}
My code is open-sourced and can be found at https://github.com/surajcm/Poseidon, I will try to troubleshoot on my own and will share the updates if I am able to resolve this issue
Solution
The problem is the password encoder. It is required to build the auto-configured UserDetailsService
that you inject in the contructor of the class.
You can break the cycle by making the bean factory method static
:
@Bean
public static BCryptPasswordEncoder bcryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
You can also move the factory method to different configuration class. But in my opinion, your WebSecurityConfig
is the canonical place for the method.
Answered By - Henning
Answer Checked By - Marilyn (JavaFixing Volunteer)