I am little confuse of Refresh Token in OAuth2.
Like it says access token limit the time window of 1 hour that hacker can use the user credentials and refresh token is long live token which can be use to recreate the access token.
I am confused if someone stole the access token from cookie he can also stole the refresh token and can use the refresh token to create new access token as I have ajax request in JQuery (Client Side)
NOTE: I have created ajax request to send refresh token on server side I append the Client ID and Secret there with grant type refresh token.
I have saved both access token and refresh token in cookie and use following the ajax request to get new access token
jQuery(document).ajaxError(function(event, jqXHR, ajaxSettings, thrownError) {
//console.log('event');console.log(event);
//console.log('jqXHR');console.log(jqXHR);
//console.log('ajaxSettings');console.log(ajaxSettings);
//console.log('thrownError');console.log(thrownError);
if(jqXHR.status == 403)
{
console.log('User is not Loged in Redictet to Login Page');
}
if(jqXHR.status == 401)
{
var refresh_token = Cookies.get('refresh_token');
if(refresh_token != undefined)
{
$.ajax({
url: CONNECT_API_URL+'/refresh-token',
type: "POST",
data:{ refresh_token: refresh_token },
success: function(response, status, jqXHR){
if(response.access_token != undefined)
{
var expires_in = new Date(new Date().getTime() + response.expires_in * 1000);
var access_token = response.token_type+' '+response.access_token;
Cookies.set('access_token', access_token, { expires: expires_in });
Cookies.set('refresh_token', response.refresh_token, { expires: 14 });
$.ajax(ajaxSettings); // Re send same ajax request with access token in cookie has been set
}
else
{
console.log('Redirect to login page.');
}
},
});
}
}
});
How should I used refresh token to enhance the security?
Here on this blog post with the title Refresh Tokens: When to Use Them and How They Interact with JWTs the topic from your question is nicely discussed.
A quote from that post:
Refresh tokens are usually subject to strict storage requirements to ensure they are not leaked.
In the RFC6819 spec they write the following about storing access tokens on the client:
5.1.6. Access Tokens
The following measures should be used to protect access tokens:
- Keep them in transient memory (accessible by the client
application only).
- Pass tokens securely using secure transport (TLS).
- Ensure that client applications do not share tokens with 3rd
parties.
And about the issuance of refresh tokens:
5.2.2.1. Restricted Issuance of Refresh Tokens
The authorization server may decide, based on an appropriate policy,
not to issue refresh tokens. Since refresh tokens are long-term
credentials, they may be subject to theft. For example, if the
authorization server does not trust a client to securely store such
tokens, it may refuse to issue such a client a refresh token.
This means you should probably think carefully on where you want to store your refresh tokens. This post Where to Store your JWTs – Cookies vs HTML5 Web Storage deals with exactly this topic.
As also mentioned in this answer on StackOverflow only the refresh_token
is not enough to get a new access_token
.
Refresh tokens, if compromised, are useless because the attacker requires the client id and secret in addition to the refresh token in order to gain an access token.
This can also be found in that same RFC6819 spec:
5.2.2.2. Binding of Refresh Token to "client_id"
The authorization server should match every refresh token to the
identifier of the client to whom it was issued. The authorization
server should check that the same "client_id" is present for every
request to refresh the access token. If possible (e.g., confidential
clients), the authorization server should authenticate the respective
client.
This is a countermeasure against refresh token theft or leakage.
Refresh tokens should be used only once. When the refresh_token
is used it will return a new access_token
and a new refresh_token
. It renders the old refresh_token
useless meaning it can no longer be used.
It also allows the authentication server to recognize that a refresh_token
was compromised, since it should only be used once. If a new renew request with the same refresh_token
comes in the authentication server knows there is something fishy going on. Not sure what is the proper way for the server to deal with such a scenario though... (maybe someone else can shine some light on this)
This is also in the RFC6819 spec:
5.2.2.3. Refresh Token Rotation
Refresh token rotation is intended to automatically detect and
prevent attempts to use the same refresh token in parallel from
different apps/devices. This happens if a token gets stolen from the
client and is subsequently used by both the attacker and the
legitimate client. The basic idea is to change the refresh token
value with every refresh request in order to detect attempts to
obtain access tokens using old refresh tokens. Since the
authorization server cannot determine whether the attacker or the
legitimate client is trying to access, in case of such an access
attempt the valid refresh token and the access authorization
associated with it are both revoked.
The OAuth specification supports this measure in that the token's
response allows the authorization server to return a new refresh
token even for requests with grant type "refresh_token".
Note: This measure may cause problems in clustered environments,
since usage of the currently valid refresh token must be ensured. In
such an environment, other measures might be more appropriate.
Your access and refresh tokens can be compromised on the client but the tokens could also be intercepted somewhere in between your client and the server.
The refresh_token
is sent only once to a client while the access_token
is being sent to the server with every request, that is why the chances of a man-in-the-middle getting his hands on your access_token
are much bigger then the chance that your refresh_token
is compromised.
In general it is good to fully understand the OAuth2 protocol so that you can properly implement it. About the security I would say in short:
- A first demand for using JWTs is a properly configured https connection between your client and the server so that all the tokens are properly encrypted when they are sent back and forth.
- A second demand is that you store the tokens in a secure way on your client.
I hope this gives you some insight on this topic. If someone wants to add or correct my post please feel free to edit/update/compliment the answer or leave a comment.