Search code examples
javaspring-bootspring-securitymicroservicesspring-security-oauth2

OAuth2RestTemplate not refreshing the oauth token upon expiry with Spring Boot 2.7.6


I am using Spring-Boot 2.7.6 with Spring-Cloud 2021.0.5 application running on VMWare Tanzu, Using OAuth2RestTemplate for authenticating my APIs with Hybris/SAP Commerce application via Feign client. However, intermittently I'm getting '401 Unauthorized' (Invalid token error) exception for my APIs.

Sample feign interface:

@FeignClient(name = "hybris", url = "${URL}", fallbackFactory = HybrisClientFallbackFactory.class, configuration = {
    HybrisFeignClientRequestInterceptor.class, FeignRetryConfiguration.class, FeignRetryer.class})
public interface HybrisClient
{

     @PostMapping("/epInternal/order/order-history")
     OrderHistoryResponse getOrderHistory(OrderHistoryRequest orderHistoryRequest);
}

Feign request interceptor:

public class HybrisFeignClientRequestInterceptor {

  @Qualifier("hybrisOAuth2RestTemplate")
  private final OAuth2RestTemplate hybrisOAuth2RestTemplate;

  @Bean
  public RequestInterceptor apigeeHybrisOauth2RequestInterceptor() {
     return (requestTemplate) -> {
         requestTemplate.header("Authorization", new String[]{String.format("%s %s", "Bearer", this.hybrisOAuth2RestTemplate.getAccessToken().getValue())});
         requestTemplate.header("x-api-key", new String[]{clientId});
     };
   }
}

The above code works seamlesly with old spring boot version for the same application (which is running in Prod) But intermittently fails with SB-2.7.6. When it fails, until system restart it keeps failing.

On further investigation found that, it fails only on one instance at the same time it works fine on the other instance of the application and both uses different access tokens at that time (Found this info from log)


Solution

  • Whenever oauth token expires_in value is 0 (In a rare cases) for the Hybris oauth token response, The older version of Spring-security-oauth2 (2.4.0 & below) was setting the expiresAt (Token expiration date time used to validate the token) as curent date, However, Spring-security-oauth2 2.5.0 sets the expiresAt value as null in the above scenario, due to this whenever Oauth2RestTemplate is checking token validity it is wrongly identifying it as valid always. Hence the refresh token won't be called until service re-start.

    Work around:

    Downgraded the Spring-security-oauth2 version to 2.4.0