9

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?

Arian
  • 7,397
  • 21
  • 89
  • 177
  • Does it prevent the context to be fully initialized ? IMHO there 2 different kind of dependencies involved here: One **static** dependency: Both your classes depends on AuthenticationManager. And AppSecurityConfig depends on JwtAuthenticationFilter. Nothing circular so far. And one **dynamic** dependency, where JwtAuthenticationFilter depends on AppSecurityConfig for its runtime initialization. – Benoit Sep 28 '18 at 07:48
  • Also it's not clear from the code snippet why you need a JwtAuthenticationFilter inside AppSecurityConfig. I would try to remove this dependency. – Benoit Sep 28 '18 at 07:53
  • I don't get this error when running in eclipse, but when I build the app and refresh its gradle dependencies in terminal using `sudo ./gradlew build --refresh-dependencies` it errors: java.lang.IllegalStateException: Failed to load ApplicationContext – Arian Sep 29 '18 at 00:51
  • I updated the code to show why I need `JWTAuthenticationFilter` in `AppSecurityConfig` – Arian Sep 29 '18 at 00:52
  • 1
    Correct me if I'm wrong, `AuthenticationManager` which is needed in `JWTAuthenticationFilter` is initialized in `AppSecurityConfig`, and `AppSecurityConfig` has `JWTAuthenticationFilter` wired in. Doesn't this form a circular dependency ? – Arian Sep 29 '18 at 00:53

1 Answers1

5

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();
} 
Arian
  • 7,397
  • 21
  • 89
  • 177