Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh OAuth2 token with Spring Security 5 OAuth2 client and RestTemplate

Spring Security 5.1.0.M2 (release notes) added support for automatic refreshing of tokens when using WebClient. However, I am using RestTemplate. Is there a similar mechanism for RestTemplate or do I need to implement that behavior myself?

The OAuth2RestTemplate class looks promising but it's from the separate Spring Security OAuth module and I would like to use plain Spring Security 5.1 on the client if possible.

like image 486
Steffen Harbich Avatar asked Sep 27 '18 09:09

Steffen Harbich


2 Answers

OAuth2RestTemplate Will refresh tokens automatically. RestTemplate will not (refresh tokens is part of the OAut2 spec, hence the OAuth2RestTemplate.

You have 2 options:

  1. Use Spring Security OAuth2 module and everything will work pretty much out of the box (configuration properties provided by Spring)
  2. Create your own RestTemplate based on Spring's OAut2RestTemplate

Spring's OAuth2 module will be integrated into Spring Security in the future. I would go for option 1.

like image 73
JohanB Avatar answered Oct 25 '22 06:10

JohanB


OAuth2RestTemplate should be used instead of RestTemplate when JWT authentication is required. You can set AccessTokenProvider to it, which will tell how the JWT token will be retrieved: oAuth2RestTemplate.setAccessTokenProvider(new MyAccessTokenProvider());

In class implementing AccessTokenProvider you need to implement obtainAccessToken and refreshAccessToken methods. So in obtainAccessToken method it can be checked if token is expired, and if it is - token is retrieved through refreshAccessToken. Sample implementation (without the details of actual token retrieval and refreshing):

public class MyAccessTokenProvider implements AccessTokenProvider {

    @Override
    public OAuth2AccessToken obtainAccessToken(OAuth2ProtectedResourceDetails details, AccessTokenRequest parameters)
        throws UserRedirectRequiredException, UserApprovalRequiredException, AccessDeniedException {
        if (parameters.getExistingToken() != null && parameters.getExistingToken().isExpired()) {
            return refreshAccessToken(details, parameters.getExistingToken().getRefreshToken(), parameters);
        }

        OAuth2AccessToken retrievedAccessToken = null;
        //TODO access token retrieval
        return retrievedAccessToken;
    }

    @Override
    public boolean supportsResource(OAuth2ProtectedResourceDetails resource) {
        return false;
    }

    @Override
    public OAuth2AccessToken refreshAccessToken(OAuth2ProtectedResourceDetails resource,
                                                OAuth2RefreshToken refreshToken, AccessTokenRequest request)
        throws UserRedirectRequiredException {

        OAuth2AccessToken refreshedAccessToken = null;
        //TODO refresh access token
        return refreshedAccessToken;
    }

    @Override
    public boolean supportsRefresh(OAuth2ProtectedResourceDetails resource) {
        return true;
    }
}

Did not find a way for Spring to call the refreshAccessToken automatically, if someone knows how to do that - please share.

like image 27
Adomas Avatar answered Oct 25 '22 06:10

Adomas