I'm working on a small project including web using react and rest api using spring data rest which all packaged in a jar. The web and api are all protected by Spring Security, default configuration for form login, and using @PreAuthorize annotation like @PreAuthorize("hasRole('ADMIN')") on repository methods. After login, if the user has the permission, everything is fine; but if not, the request will wait a long time (minutes), and return http status 26.
Spring Boot version is 2.7.0
I've tried using spring-session-jdbc and X-Auth-Token header, but still the same.
Security configurations:
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests().anyRequest().authenticated()
.and()
.csrf().disable()
.cors(Customizer.withDefaults())
.formLogin();
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
configuration.addAllowedOrigin("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", configuration);
return source;
}
}
the repository endpoint:
public interface UserRepository extends JpaRepository<User, String> {
@PreAuthorize("hasRole('ADMIN')")
<S extends User> S save(User u);
@PreAuthorize("hasRole('USER')")
List<User> findByNameContains(String name);
the test request and response header:
curl -X POST -H 'Content-Type: application/json; charset=utf8;' -i 'http://xxxxxxxxxxxx:8080/api/users' --data '{
"username": "john.m",
"name": "John Murdoch"
}'
# response header
Status Code: 26
access-control-allow-origin: *
cache-control: no-cache, no-store, max-age=0, must-revalidate
connection: keep-alive
date: Mon, 10 Oct 2022 00:58:34 GMT
expires: 0
keep-alive: timeout=60
pragma: no-cache
vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
x-content-type-options: nosniff
x-frame-options: DENY
x-xss-protection: 1; mode=block
I FOUND the problem, I configured a global Exception Handler to deal with AccessDeniedException but forget why, and it cause the problem. After removing that config, response became normal 403.
@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ AccessDeniedException.class })
public ResponseEntity<Object> handleAccessDeniedException(Exception ex, WebRequest request) {
return new ResponseEntity<Object>(
ex.getLocalizedMessage(),
new HttpHeaders(),
HttpStatus.FORBIDDEN.ordinal());
}
...
}
CodePudding user response: