I am implementing an OAuth2 server that supports refresh token however, there is something that I am not been able to understand fully.
When a user request for a new access token via the refresh_token grant_type and he/she requested lesser scope (3 out of the 5 scopes) than what the original access token has. Should the refresh token have the original scopes or should the refresh token have the new scopes requested?
If the refresh token has the new scopes requested, does this mean that eventually, they will run out of scopes if they keep requesting lesser scopes?
Should the refresh token keep the original scopes? This would mean that an access token returned would have different scopes as to what is stored in the refresh token, and the next request to get a new access token may result in more scopes than the current access token.
Can someone please enlighten me on this issue?
I have read the RFC docs and there is a point that states
If a new refresh token is issued, the refresh token scope MUST be
identical to that of the refresh token included by the client in the
request.
For a refresh token grant:
The base behaviour is to receive only a new access token in the response
The original refresh token is then reused a number of times.
Some authorization servers support refresh token rotation and may also:
Issue a new 'rolling' refresh token
This is bound to the original scopes and session time
At least that's the theory, though you need to test for your particular authorization server. Vendor support from the likes of Microsoft, AWS and others varies considerably.
Related
As we know that access token gives the client to access resources from resource server, I would like to know the contents and the process that happens with refresh token to get new access token.
I was tryging to experiment how oauth2 works, but got stuck at what refresh token does.
I would like to know the contents and the process that happens with
refresh token to get new access token.
Refresh token are generally opaque token (random unique string).
Refresh token is used to get new access token from the Authorization Server. Refresh tokens typically remain valid for longer time as compared to access token. In a typical client-server flow, when the access token expired, server reject the request then client uses the earlier obtained refresh token to get a new access token from Authorization Server. By doing so authentication between client and server remain uninterrupted and no re-authentication needed. Once the refresh token expired, client has to go through the complete authentication flow which usually require user intervention.
I have a refresh token in hand, a client_id and a client_secret.
I'd like to determine which end-user the refresh token corresponds to, and/or which scopes.
Is that possible, and, if so, what's the best way to go about that?
Most commonly refresh tokens are opaque unreadable values that map to state stored in the Authorization Server.
Some providers may issue refresh tokens as JWTs, in which case you can read the values. Your code will not be portable though, so this is not advised.
CLIENT
Usually an OAuth client gets a refresh token from the Authorization Server (AS) after user authentication. Later on the client can try to renew access tokens with it.
AUTHORIZATION SERVER
This is the standard component for issuing and renewing refresh tokens and the typical behaviour is like this:
When a user authenticates, record details of the 'delegation' in a database row
Typical fields stored are a SHA256 hash of the refresh token, the user and client IDs, and the issued / expiry times of the grant
This information enables the AS to receive and validate token refresh requests.
ISSUING YOUR OWN REFRESH TOKENS
This should only need to be done if you don't have an AS. In this case follow the AS pattern above. It is recommended instead to use an AS to do it for you though - eg the free edition of Curity from the above link.
I see most of people saying when we use refresh token to exchange for a new access token, the auth server would issue a new refresh token and invalid the previous one. Refer
OAuth Refresh Token Best Practice
But from the OAuth website
https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/
It says the auth server can "optionally issue a new fresh token in response, or if we don't include a new refresh token, the client assumes the current refresh token will continue to be valid"
So, it looks like both options (keep or renew refresh token) are acceptable to OAuth2 standard.
My questions are:
1) Do both options are equally secure?
2) If the auth server returns a new refresh token but the client fails to receive (e.g. network error), the client has no way to re-gain access token with existing refresh token, which already invalidated. Correct?
3) If the refresh token has been leaked to someone else, both the attacker and the victim client can use it. If the auth server takes the renewal approach, then only the first one to use the refresh token can re-gain access token. So, if the victim found the refresh token is no longer valid, it may think that the refresh token has been compromised. Is this the reason for the "renewal approach"?
2.) Yes, that's correct.
3.) That's correct too. You can take a look at the OAuth 2.0 for Browser-Based Apps RFC which discusses the refresh token regeneration. It's important mainly for public clients - the ones without client_secret, since a refresh token can be exchanged for an access token right away.
1.) Refresh token regeneration is a security feature - it shortens validity of a stolen refresh token and it enables the auth server to detect that refresh token had been compromised. So it's more secure to use it than not. But it may be more convenient for private clients not to get a new refresh token on each use - for example to prevent the refresh token loss due to network error - as you described it in point #2.
Once I've completed the OAuth flow by obtaining authorization from the user and then creating an access token, how do I obtain another token without asking the user for authorization again? I thought the user's account on Smartsheet would remember that they trusted the application, but that doesn't seem to be the case. I'm new to OAuth so I'm sorry if I'm missing something obvious.
Thanks!
Access tokens retrieved via the OAuth flow are valid only for a certain period of time -- you (i.e., your application) can refresh a token before it expires in order to prevent the end-user from having to provide authorization again.
When you issue a GET Token request to obtain an access token, the response contains not only the token itself, but also information to indicate how long the token is valid (the expires_in property indicates the number of seconds until the token expires) and a refresh_token property value that you'll need in order to refresh the token.
To prevent the user from having to provide authorization again, simply refresh the token before it expires, and then use the new (refreshed) token value in subsequent API requests. Note that each token you obtain (whether it's the original token or a refresh token) will always expire in a finite amount of time, thereby requiring that you refresh the token in order for your application to maintain user authorization.
I am implementing an oauth server using spring oauth. I notice that spring's implementation re issues the same access token if not expired from the token endpoint. However the behavior is different while refreshing access tokens. A new token is reissued each time, are there any concerns to keep in mind if I were to reissue the same un expired access token on receiving a valid refresh request.
The OAuth Spec section-6 specifies that:
The authorization server MAY issue a new refresh token, in which case
the client MUST discard the old refresh token and replace it with the
new refresh token. The authorization server MAY revoke the old
refresh token after issuing a new refresh token to the client. If a
new refresh token is issued, the refresh token scope MUST be
identical to that of the refresh token included by the client in the
request.
There does not seem to be a requirement that the access token is brand new.
I think the main concern is to ensure that you do not change the expiration date on an existing token. And that you correctly return to the client an accurate expires_in property which reflects when the token will expire.
In addition, it might make the semantics confusing for clients. The refresh is usually done when a token is expired, and the client wants a new one.
I can imagine some odd edge cases. A client could send a request to refresh a token a few seconds before it is expired (perfectly valid logic for a client), but still receive back the same token which is almost expired.