neaGaze
neaGaze

Reputation: 1461

OAuth2 refresh_token logic implementation in spring-security-oauth2

I have successfully implemented the request for new token in OAuth2 for this request:

    curl --request POST --url https://some-autentication-server.com/token --header 'content-type: content-type'

with the body provided as:

{
  "grant_type"="password",
  "username"="username",
  "password"="password"
  "client_id"="my-client-id"
}

After the authentication the resource server curl can be accessed as:

curl -i -H "authorization: Bearer token-received-from-auth-server" \ 
-H "accept: application/json" \
-H "request-id: abcdef" \
-H "consent-status: optedIn" \
-X GET https://my-resource-server.com/path

The configuration I've used in Spring Boot is this:

@EnableOAuth2Client
@Configuration
public class OauthClientConfig {

    @Bean
    public CloseableHttpClient httpClient() throws Exception {
        CloseableHttpClient httpClient = null;
        try {

            httpClient = HttpClientBuilder.create()
                         .setProxy(new HttpHost("PROXY_HOST_NAME", 3000, "http"))
                         .build();

        } catch (Exception e) {
            throw e;
        }
        return httpClient;
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(CloseableHttpClient httpClient) throws Exception {

        ClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        ((HttpComponentsClientHttpRequestFactory) clientHttpRequestFactory)
                .setReadTimeout(10000);
        ((HttpComponentsClientHttpRequestFactory) clientHttpRequestFactory).setConnectTimeout(10000);
        return clientHttpRequestFactory;
    }

    @Bean
    @Qualifier("restTemplate")
    @Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
    public OAuth2RestOperations restTemplate(OAuth2ProtectedResourceDetails oAuth2Resource,
            ClientHttpRequestFactory clientHttpRequestFactory, AccessTokenProvider accessTokenProvider)
            throws Exception {

        Map<String, String[]> map = new HashMap<>();
        AccessTokenRequest tokenRequest = new DefaultAccessTokenRequest(map);
        OAuth2RestTemplate restTemplate = new OAuth2RestTemplate(oAuth2Resource,
                new DefaultOAuth2ClientContext(tokenRequest));
        restTemplate.setRequestFactory(clientHttpRequestFactory);
        restTemplate.setAccessTokenProvider(accessTokenProvider);
        return restTemplate;
    }

    @Bean
    public AccessTokenProvider accessTokenProvider(ClientHttpRequestFactory clientHttpRequestFactory,
            OAuth2ProtectedResourceDetails oAuth2Resource) throws Exception {
        ResourceOwnerPasswordAccessTokenProvider accessTokenProvider = new ResourceOwnerPasswordAccessTokenProvider();
        accessTokenProvider.supportsRefresh(oAuth2Resource);
        accessTokenProvider.setRequestFactory(clientHttpRequestFactory);
        return new AccessTokenProviderChain(Arrays.<AccessTokenProvider>asList(accessTokenProvider));
    }

    @Bean
    @Qualifier("oAuth2Resource")
    public OAuth2ProtectedResourceDetails oAuth2Resource() {
        ResourceOwnerPasswordResourceDetails oAuth2Resource = new ResourceOwnerPasswordResourceDetails();
        oAuth2Resource.setId("MY_ID");
        oAuth2Resource.setAccessTokenUri("TOKEN_URL");
        oAuth2Resource.setClientId("TOKEN_CLIENTID");
        oAuth2Resource.setClientSecret("TOKEN_CLIENT_SECRET");
        oAuth2Resource.setScope(new ArrayList<String>(Arrays.asList(new String[]{"read"})));
        oAuth2Resource.setUsername("TOKEN_USERNAME");
        oAuth2Resource.setPassword("TOKEN_PAZZWORD");
        oAuth2Resource.setTokenName("access_token");
        oAuth2Resource.setGrantType("password");
        return oAuth2Resource;
    }   
}

This works fine for the new token request, but now I want to be able to write a logic for implementing the refresh_token. Ideally, I want to store the tokens before it's expiry time and as soon as the token expiry reaches to about 90% of its expiry time, the refresh token logic would run hit the authentication server to refresh the token. The refresh token logic would run in the background all the time. My question is how to implement this logic using the spring-security-oauth2 library? Is this logic already implemented in the library or do I have to manually write the logic myself?

Upvotes: 0

Views: 6220

Answers (1)

Naveen
Naveen

Reputation: 402

I want to store the tokens before it's expiry time and as soon as the token expiry reaches to about 90% of its expiry time, the refresh token logic would run hit the authentication server to refresh the token.

This is not according to oauth RFC .
https://www.rfc-editor.org/rfc/rfc6749#section-1.5

Only Once client gets an error from the resource server that the previous token is not valid , refresh token is used to get new token . Look at steps E to G in the above link .

The Spring oauth2.0 supports the flow as per oauth . Here is blog post which I found regarding that .

Upvotes: 5

Related Questions