gotchajavaspringModerate
Spring Security: permitAll() still triggers authentication for some requests
Viewed 0 times
permitAllSpring Security401403JWT filterauthentication entry pointstateless
Problem
Adding .requestMatchers("/public/**").permitAll() to the security config still causes some requests to receive 401 or 403 responses. The filter chain runs authentication checks before authorization, so a malformed or expired token triggers rejection before permitAll is evaluated.
Solution
Configure the authentication failure handler to not reject requests for permitted paths, or use a stateless security config that handles missing tokens gracefully:
In the JWT filter, skip processing if no Authorization header is present rather than throwing for missing tokens.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**", "/actuator/health").permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(ex -> ex
.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}In the JWT filter, skip processing if no Authorization header is present rather than throwing for missing tokens.
Why
Spring Security's filter chain runs regardless of authorization rules. A JWT filter that throws an exception for any request without a valid token will reject requests to permitted paths because the exception fires before authorization evaluation.
Gotchas
- CSRF protection is enabled by default — stateless REST APIs should disable it
- The order of requestMatchers matters; more specific patterns should come before general ones
- Spring Security 6.x removed WebSecurityConfigurerAdapter — use SecurityFilterChain beans instead
Revisions (0)
No revisions yet.