The FilterSecurityInterceptor and AuthorizationFilter now apply to every request by default.
This led to a problem from the Spring Boot's perspective:
Consider the following configuration:
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) {
http.authorizeHttpRequests(requests -> requests
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
);
return http.build();
}
If a request is made to GET /public/notfound with no credentials, then we expect a 404 - Not Found. Instead, Spring Boot will handle the exception and forward the request to /error with DispatcherType.ERROR. The /error endpoint is protected, an AuthenticationException is thrown and ExceptionTranslationFilter transforms it to a 401 - Unauthorized.
We should consider adding an option to ExceptionTranslationFilter that configures it to swallow the Spring Security exceptions from specified DispatcherTypes. Something like:
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) {
...
http.exceptionHandling(exception -> exception
.swallowExceptionsForDispatcherTypes(List.of(DispatcherType.ERROR))
);
return http.build();
}
This way we keep the original response status code but apply all the authorization rules to that endpoint.
See: - https://github.com/spring-projects/spring-security/issues/11027 - https://github.com/spring-projects/spring-security/issues/11466 - https://github.com/spring-projects/spring-security/issues/10919 - https://github.com/spring-projects/spring-boot/issues/31703
Comment From: marcusdacoregio
For 6.0 the default can be to swallow the exceptions for DispatcherType.ERROR.
Users could always return to the old behavior by doing:
@Bean
SecurityFilterChain appSecurity(HttpSecurity http) {
...
http.exceptionHandling(exception -> exception
.swallowExceptionsForDispatcherTypes(Collections.emptyList())
);
return http.build();
}