In my Spring boot app, I have the following two classes:
@EnableWebSecurity
public class AppSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// TODO re-enable csrf after dev is done
.csrf()
.disable()
// we must specify ordering for our custom filter, otherwise it
// doesn't work
.addFilterAfter(jwtAuthenticationFilter,
UsernamePasswordAuthenticationFilter.class)
// we don't need Session, as we are using jwt instead. Sessions
// are harder to scale and manage
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
and:
@Component
public class JwtAuthenticationFilter extends
AbstractAuthenticationProcessingFilter {
/*
* we must set authentication manager for our custom filter, otherwise it
* errors out
*/
@Override
@Autowired
public void setAuthenticationManager(
AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authenticationManager);
}
}
JwtAuthenticationFilter
depends on an AuthenticationManager
bean through its setAuthenticationManager
method, but that bean gets created in AppSecurityConfig
which has JwtAuthenticationFilter
autowired in. This whole thing creates a circular dependency.
How should I resolve this issue?
4.2. A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.
Circular dependency in Spring happens when two or more beans require instance of each other through constructor dependency injections. For example: There is a ClassA that requires an instance of ClassB through constructor injection and ClassB requires an instance of class A through constructor injection.
Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications. Spring Security is a framework that focuses on providing both authentication and authorization to Java applications.
and, yes, cyclic dependencies are bad: They cause programs to include unnecessary functionality because things are dragged in which aren't needed. They make it a lot harder to test software.
I fixed this issue by following what was suggested here: Cannot pass AuthenticationManager to custom filter by @Autowired
I removed @Component
from JwtAuthenticationFilter
and instead of autowiring JwtAuthenticationFilter
to WebSecurityConfig
class, I defined the bean there:
@Bean
public JwtAuthenticationFilter JwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With