Disable refresh_token attribute(s) in refresh_token grant type

Not applicable

I have a flow that generates an oauth2 access token and also provides a refresh token (with expiry). When I use the refresh token to obtain a new access token, I would like to prevent the response from containing a new refresh token value (with expiry). Is there any way to do this other than limiting the number of times that the refresh_token policy is invoked? In short, I only want one refresh token to be used by the end user instead of multiple (i.e. the one on the original oauth token request, not the one on the refresh_token request).

Here is a sample to assist:

Response from request to generate an oauth token:

{
  "issued_at": "1492009708510",
  "scope": "",
  "application_name": "0eb7f33a-5c84-4751-aae4-8d4f18f25705",
  "refresh_token_issued_at": "1492009708510",
  "status": "approved",
  "refresh_token_status": "approved",
  "api_product_list": "[<removed>]",
  "expires_in": "1799",
  "developer_email": "<removed>",
  "token_type": "BearerToken",
  "refresh_token": "sn3JwgyRV02itBrCIJgSVrEwIMmGTgxT",
  "client_id": "<removed>",
  "access_token": "0VxvGIXLo0B7rFKxNDjbshiWRvfk",
  "organization_name": "<removed>",
  "refresh_token_expires_in": "28799",
  "refresh_count": "0"
}

Here is the response from the refresh_token request using the refresh_token value from the original request ('sn3JwgyRV02itBrCIJgSVrEwIMmGTgxT')

{
  "issued_at": "1492009846489",
  "scope": "",
  "application_name": "0eb7f33a-5c84-4751-aae4-8d4f18f25705",
  "refresh_token_issued_at": "1492009846489",
  "status": "approved",
  "refresh_token_status": "approved",
  "api_product_list": "[<removed>]",
  "expires_in": "1799",
  "developer_email": "<removed>",
  "token_type": "BearerToken",
  "refresh_token": "GnnxrqT98kFjVT3o11eoxxAeGYjvonLr",
  "client_id": "<removed>",
  "old_access_token_life_time": "137984",
  "access_token": "GvVZ7yV1LrlUUEEaI8M8uDRGehmg",
  "organization_name": "<removed>",
  "refresh_token_expires_in": "0",
  "refresh_count": "1"
}

Basically, I want to prevent the 'refresh_token' and 'refresh_tokens_expires_in' attributes from being returned in the response back to the client to avoid them using the second refresh token value. The client should still be able to receive new access tokens using the original refresh_token value until it expires.

0 4 770
4 REPLIES 4

Not applicable

I have done some more through testing and think I understand what is happening but would like further confirmation from the group. Here is what I believe to be true:

1. Each refresh_token value can be used in the 'refresh_token' password grant for a new access token.

2. Once the refresh_token value has been used to generate a new access token, it becomes invalid.

3. You can have multiple access tokens valid at the same time and each maintains their own expires_in value along with the accompanying refresh_token expires_in value

I did some testing with a VerifyAccessToken operation where I submitted several refresh_token requests sequentially. I was able to get up to 4 access tokens to be valid at the same time before some of them started to become invalid for some reason (they were not expired). I am wondering if Apigee has a limit on the number of 'refresh sequences' that can be done starting with an original token.

Hey Chris, seems like you have a set of related questions.

But I will confirm: by default Apigee Edge treats refresh tokens as use-once things. But you can change this behavior, so that a single refresh token can be used to obtain multiple distinct access tokens.

In the OAuthV2 policy, there is a ReuseRefreshToken element that enables this.You may have missed this option. See the doc.

4659-reuse-refresh-token.png

as for this statement:

You can have multiple access tokens valid at the same time and each maintains their own expires_in value along with the accompanying refresh_token expires_in value.

I think what you are seeing is a stale cache. The access tokens will be cached by the MP after they are presented, for 180s or for the lifetime of the token, whichever is shorter.

When you use a refreshtoken to get a new access token, the existing access token is invalidated in the store, but not in the cache. (This is by design.) So the previously valid access token may continue to be treated as valid, even after you use the refresh token associated to it, to get a new access token. But really, you should be using the new access token.

Hi Dino,

Yup, I missed that option, thanks for pointing it out. This will resolve my concern over multiple refresh tokens in play at one time.

Regarding your comments on the stale cache, I am not sure what 'MP' refers to (is this message processor?). You indicate that the existing access token is invalidated in the store but yet using a VerifyAccessToken method indicates that it is still valid. Does this mean that if the caller submits a request to a protected API with the (expired in the store but still valid according to the cache) access token, that the request would succeed? If it would succeed, is there a way to invalidate the cache such that it would fail (perhaps as an option on the RefreshAccessToken operation or by adding a RevokeToken operation as part of a refresh token flow in our API?). In short, we would like to ensure that we only have one valid access token available at a time.

The stale cache might explain why I was seeing inconsistent results with the VerifyAccessToken operation. At some point the multiple access tokens I had on the go would return back as invalid (via a VerifyAccessToken operation) even though the expiry time had not been reached.

Not applicable

One other piece of information I should add is that in our test environment there are two routers and two message processors. Is it possible that the one route/message processor is reusing the stale cache and the other pair is retrieving information from the Apigee store? If so, is there a method by which we can validate our test enviornment setup (we have an on-prem setup).

One alternative that I am thinking about is to request the original access token as part of the refresh request and then adding a policy to specifically revoke the original access token. Perhaps this would flush the cache and return consistent results? We really shouldn't need the original access token to do a refresh request but also do not want inconsistent results in our message processing.