Home > database >  Spring bean dependencies in the application context form a cycle
Spring bean dependencies in the application context form a cycle

Time:01-10

I've been trying to add jwt authorisation to my project. I've already tried adding @Lazy, that doesn't work. I don't know how can I update my app to remove the dependency cycle.

Console:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  jwtAuthenticationFilter defined in file [C:\Users\User\Desktop\PizzaCloud2\target\classes\pizzas\security\authentication\JwtAuthenticationFilter.class]
↑     ↓
|  securityConfig defined in file [C:\Users\User\Desktop\PizzaCloud2\target\classes\pizzas\security\SecurityConfig.class]
└─────┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

JwtAuthenticationFilter class:

@Component
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter{
    
    private final JwtService jwtService;
    private final UserDetailsService userDetailsService;

    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request, 
            @NonNull HttpServletResponse response, 
            @NonNull FilterChain filterChain)
                    throws ServletException, IOException {
        
        final String authHeader = request.getHeader("Äuthorization");
        final String jwt;
        final String username;
        if (authHeader == null || !authHeader.startsWith("Bearer")) {
            filterChain.doFilter(request, response);
            return;
        }
        jwt = authHeader.substring(7);
        username = jwtService.extractUsername(jwt);
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if (jwtService.isTokenValid(jwt, userDetails)) {
                UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
                    userDetails, userDetails.getAuthorities()
                );
                authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authToken);
            }
        }
        filterChain.doFilter(request, response);
    }
    
    
}

SecurityConfig class:

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
    
    
    private final JwtAuthenticationFilter jwtAuthFilter;
    
    private final AuthenticationProvider authenticationProvider;
  
    @Bean
    public UserDetailsService userDetailsService(UserRepository userRepo) {
        return username -> {
            User2 user = userRepo.findByUsername(username);
            if (user != null) {
                return user;
            }
            throw new UsernameNotFoundException(
                    "User '"   username   "' not found");
        };
    }
  
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        
        http
        .authenticationProvider(authenticationProvider)
        .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        
        return http.csrf()
                .disable()
                /*.authorizeRequests()*/
                .authorizeHttpRequests()
                .requestMatchers("/design", "/orders").hasRole("USER")
                .anyRequest().permitAll()
                /*.anyRequest().authenticated()*/
              
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
              
                .and()
                .formLogin()
                .loginPage("/login")

                .and()
                .logout()
                .logoutSuccessUrl("/")

      // Make H2-Console non-secured; for debug purposes
              /*.and()
              .csrf()
              .ignoringRequestMatchers("/h2-console/**")*/

      // Allow pages to be loaded in frames from the same origin; needed for H2-Console
                .and()  
                .headers()
                .frameOptions()
                .sameOrigin()
        
                .and()
                .build();
        }

}

Setting spring.main.allow-circular-references to true doesn't help.

CodePudding user response:

As the error indicating: "Relying upon circular references is discouraged and they are prohibited by default..."

  • JwtAuthenticationFilter refer UserDetailsService in SecurityConfig

  • SecurityConfig refer JwtAuthenticationFilter

Solution: You can move @Bean UserDetailsService to another configuration class

  • Related