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:\Users\Blade\Documents\WebMent\modules\backend\build\classes\java\main\com\shortsdesigns\webment\configuration\AppConfig.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?
CodePudding user response:
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.