I have a @EnableResourceServer which checks a JWT on requests. This JWT has a 30 seconds TTL, it is accepted by my REST API. But sometimes the process takes more than 30 seconds before the response is sent.
Even if my app returns a 200 response code, Spring replaces it with a 401, meaning my JWT has expired.
I think it's a bad behavior, JWT should not been checked on response. Did someone experience the same issue and know how to avoid it ?
I use Spring boot 1.5.10.RELEASE, spring-security-oauth2 2.2.1.RELEASE, spring-security-jwt 1.0.9.RELEASE.
My class :
@EnableResourceServer
@Configuration
@Profile("security")
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.requestMatchers().and().authorizeRequests().antMatchers("/pay/**").authenticated();
}
}
and I'm using the property :
security.oauth2.resource.jwt.key-uri=
Here a log proving the call is made twice :
2018-03-27T15:07:48.801-04:00 [APP/PROC/WEB/0] [OUT] 2018-03-27 19:07:48.800 DEBUG [accueil-transfert,c0baad95368697cd,c0baad95368697cd,true] 15 --- [io-8080-exec-10] p.a.OAuth2AuthenticationProcessingFilter : Authentication success: org.springframework.security.oauth2.provider.OAuth2Authentication@822a1a7a: Principal: null; Credentials: [PROTECTED]; Authenticated: true; Details: remoteAddress=xxx.xxx.xxx.xxx, tokenType=BearertokenValue=<TOKEN>; Not granted any authorities
...
2018-03-27T15:08:39.130-04:00 [APP/PROC/WEB/0] [OUT] 2018-03-27 19:08:39.129 DEBUG [accueil-transfert,c0baad95368697cd,c0baad95368697cd,true] 15 --- [nio-8080-exec-1] p.a.OAuth2AuthenticationProcessingFilter : Authentication request failed: error="invalid_token", error_description="Access token expired: eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiAiUElTR...
The request is stored in a completableFuture in my RestController:
@PostMapping("/myUrl")
public CompletableFuture<ResponseEntity<CorpsReponseDto>> effectue(@RequestHeader HttpHeaders enteteRequete,
@Valid @RequestBody CorpsRequeteDto corpsRequete, BindingResult bindingResult) {
CompletableFuture<ResponseEntity<CorpsReponseDto>> future = new CompletableFuture<>();
...
return future;
}
And completed in a @Service class :
future.complete(new ResponseEntity<>(reponseDto, httpStatus));
Thanks a lot for your help.
Reason is that the 'filterChain' is called once for REQUEST type (used for HTTP request reception) and once for Async type (the one used in CompletableFuture on response process).
There is one property to set to avoid the Async chain :
(seen on https://github.com/spring-projects/spring-security-oauth/issues/736)