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