so I have this section of code in AppConfig.java:
@Configuration @EnableWebSecurity public class AppConfig extends WebSecurityConfigurerAdapter { private final CurrentUserService currentUserService; private final SessionFilter sessionFilter; private final PasswordEncoder passwordEncoder; @Autowired @Lazy public AppConfig(CurrentUserService currentUserService, SessionFilter sessionFilter, PasswordEncoder passwordEncoder) { this.currentUserService = currentUserService; this.sessionFilter = sessionFilter; this.passwordEncoder = passwordEncoder; } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(currentUserService).passwordEncoder(passwordEncoder); } @Override protected void configure(HttpSecurity http) throws Exception { http = http.cors().and().csrf().disable(); http = http.exceptionHandling().authenticationEntryPoint( (request, response, authException) -> { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage()); } ).and(); http.authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated(); http.addFilterBefore(sessionFilter, UsernamePasswordAuthenticationFilter.class); } @Override @Bean public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
if I get rid of the @Lazy it will not start, i have tried to get rid of the constructor and do:
@Autowired private final CurrentUserService currentUserService; @Autowired private final SessionFilter sessionFilter; @Autowired private final PasswordEncoder passwordEncoder; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(currentUserService).passwordEncoder(passwordEncoder); }
same thing, can someone please help me out, I really don’t want to have to use the @Lazy Implementation. here is the error it returns:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'appConfig' defined in file [C:UsersBladeDocumentsWebMentmodulesbackendbuildclassesjavamaincomshortsdesignswebmentconfigurationAppConfig.class]: Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'appConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
When getting rid of the constructor and using field injection it gives me this error:
Error creating bean with name 'appConfig': Unsatisfied dependency expressed through field 'passwordEncoder'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'appConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
Advertisement
Answer
This error occurs because you’re creating the PasswordEncoder
in the same class that you’re injecting it.
The best solution is to not autowire the PasswordEncoder
(or the CurrentUserService
) at all.
It appears those instances are only used in the configure(AuthenticationManagerBuilder auth)
method, which is redundant.
Registering a PasswordEncoder
and UserDetailsService
as a bean is enough for Spring Security to detect them and use them in your configuration.
In other words, you should remove the following code:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(currentUserService).passwordEncoder(passwordEncoder); }
The application will still behave in the exact same way.