Я не уверен, почему Spring продолжает возвращать 403, хотя я добавил разрешениеAll в requestMatchers. Я использую собственный JWTAuthenticationFilter, но не думаю, что это является причиной проблемы.
Я пробовал разные способы устранения этой проблемы, но мне удалось устранить ее только без использования Spring Starter Security или AnyRequest для разрешения All.
Что-то мне не хватает?
Конфигурация безопасности
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(CsrfConfigurer::disable)
.sessionManagement(sess -> sess.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers(HttpMethod.POST, "/api/user/test").permitAll()
.requestMatchers("/error").permitAll()
.anyRequest().authenticated() // others require JWT
)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
Конфигурация JWT
public class JWTAuthenticationFilter extends OncePerRequestFilter {
// Define the paths that are permitAll() in SecurityConfig
// This list helps the filter decide how to handle invalid/missing tokens
private static final List PERMIT_ALL_PREFIXES = Arrays.asList(
"/api/user/test", // Exact match for this path
"/public/", // Prefix for paths under /public/
"/error"
);
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
// Check if an Authorization header with a Bearer token exists
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String jwt = authHeader.substring(7);
// Validate the JWT
if (JWTUtils.isValidToken(jwt)) {
// If valid, set authentication in SecurityContextHolder
Long userId = JWTUtils.getUserId(jwt);
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList());
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
} else {
// Token exists but is invalid
System.out.println("awef");
// If it's a PROTECTED path (not a permitAll path), then an invalid token means UNAUTHORIZED
// SecurityContextHolder.clearContext(); // Clear any stale or invalid context
// response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// response.getWriter().write("{\"status\": \"401\", \"message\": \"Invalid or Expired Token\"}");
// response.getWriter().flush();
// If it IS a permitAll path, an invalid token just means no authentication for this request.
// We let it proceed to the next filters, relying on the permitAll() rule to allow access.
}
}
System.out.println("After JWT filter, authentication: " + SecurityContextHolder.getContext().getAuthentication());
// If no Authorization header is present, or if it's a permitAll path with an invalid token,
// we simply continue the filter chain. Spring Security's permitAll() will allow access
// for these paths, and authenticated() will trigger the AuthenticationEntryPoint for others.
filterChain.doFilter(request, response);
}
}
Журнал отладки
2025-07-13T17:04:09.029+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing POST /api/user/test
After JWT filter, authentication: null
2025-07-13T17:04:09.030+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext
2025-07-13T17:04:09.031+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access
2025-07-13T17:04:09.032+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Securing POST /api/error
2025-07-13T17:04:09.032+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.security.web.FilterChainProxy : Secured POST /api/error
2025-07-13T17:04:09.034+09:00 DEBUG 97916 --- [test] [nio-8080-exec-5] o.s.s.w.a.AnonymousAuthenticationFilter : Set SecurityContextHolder to anonymous SecurityContext