In my web application I am using access and refresh tokens to authorize user access to protected resources, the flow is as following:
The user, through a mobile app, sends a request to the "auth/token" endpoint providing his credentials. The server authenticates the user and issue an access and refresh token. The refresh token is saved in a whitelist to be able to revoke it later on, if necessary.
Upon access token expiration, the mobile app sends the refresh token to the "/token/refresh" endpoint presenting the refresh token. A new access/refresh token pair is created and the old refresh token is invalidated ,implementing in this way the token rotation.
Now the problem:
Let's say that the client refresh the token but never receive a response back from the server because the network is lost. After 30 mins the client tries to refresh again but its token is now invalid and the user is logged out. In the Oauth implementations we can set a time for the old token after which this will be invalidated, giving the possibility to the mobile app to resend the same refresh token if any problem occurs. But I do not think this is a solution because we can't be sure of when the mobile client will retry to refresh the token. It can be in some minutes, hours or worse also days.
How do you approach this problem?
The first solution I could think of is increasing expiration time.
Related
Recently I am learning oauth 2.0, and all the docs said that when the refresh token invalid or expired and let the user to relogin. To my experience to use the apps, no apps need to relogin again after the first login. how did they do that? store the username and password and refresh the refresh token with the username and password? set the refresh token for a long time(for example, set the refresh token 5 year to expired)?how did they do that?
this is what we could silent refresh, when the client connects the first time, the token is refreshed in the background with the refresh token before the token expire, and for your refresh token, you don't need long lifetime you need just to keep the latest one.
see my other answer here
I have implemented openid connect authentication using azure active directory in my website. The session expires every 1 hour. So the user is logged out, and redirected back to the login page. While analyzing based on it, i have found a solution in the below link, to use UseTokenLifetime = false
https://github.com/aspnet/Security/issues/147
Will this fix my issue? or is there any chance of increasing the session time?
Thanks in advance
Dinesh
Read here to learn more about Configurable Token Lifetime
In general, access tokens have a very short lifetime. This is intentional. Your web application should be using the refresh token which comes with your access token to acquire new access tokens once the original one expires.
When you get an access token and refresh token (assuming all default settings), the access token will last up to one hour. The refresh token will allow you to get a new access token + refresh token pair for up to 14 days. The new refresh token you get will last another 14 days, allowing you to chain new access tokens up to a total of 90 days, where you will need to eventually ask the user to sign in again.
You have the ability to configure token lifetimes such that your "refresh token chain" will never expire, however any individual access token or refresh token will eventually expire.
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.
Say I'm developing an Evernote or YouTube client, and after the user logs in, the app gets an authorization token from the API server.
Then I use this token to interact with the server until, sometime later, the token expires.
The key is, I don't know if this token is expired until the server returns an error with a message like 'token expired'. Then I have to fetch a new token. Maybe it occurs while the user is posting a message.
So what is an elegant way to deal with this scenario? I want to combine fetching a new token with continuing the last request, so that the user just feels it works as usual.
It depends on which flow you're using. But in general, if you are able to refresh the auth token (via refresh token) without redirecting the user for credentials again, you should do it seamlessly.
Also, you should know exactly when a token is going to expire. If you're coding against an OAuth 2 implementation, the auth token response should give you an 'expires_in' field as a time span telling you exactly how long the token will expire after it was issued to you.
I'm working with an API that uses OAuth2, provides an access token that expires in 3600 seconds, and provides a refresh token with it. Originally, I'd waited for an API call to fail in a way that indicated the access token was expired and then tried to refresh the access token using the refresh token. This has become problematic when the access token is expired and several API calls are made concurrently (each call separately triggers a refresh and most of the calls fail).
Would it be better to automatically refresh the access token using the refresh token after 3600 seconds? (Or 3599 seconds or 3601 seconds?) Is there a different paradigm I should be using for refreshing the access token?
Ideally, the client should have sufficient smarts to not use an expired access token. Fortunately the response from your OAuth AS's token endpoint should include the expires_in attribute to confirm that the expiry will be in 3600 seconds. E.g.:
{"token_type":"Bearer","expires_in":3600,"refresh_token":"p8BPdo01kkjh6fhatclD3wwBEQblm4kL4ctYRVlrHo","access_token":"9XebAAXeu6hQOAiwmOk8vdhRyUFV"}
Since this JSON response is generated by the server, there's a chance that the transmission back to the client has taken time, and thus the "expires_in" value may be smaller than it appears.
Given that, I'd recommend that you have some sort of buffer (say 5-10 seconds) before expiry to automatically use your refresh token to request a new access token.
I may have used the following scenario. There will be access failures due to access token validation error but those errors will be minimal.
App1 invokes the token api with password grant type and get the access token and refresh token pair (accto1/refto1)
App2 also do the same at the starting up of the execution (accto1/refto1)
When the access token is expired for App1, he may do the refresh token by invoking the token api with refresh token grant type and with his existing refresh token (refto1) and he will retrieve a new pair of access token and refresh token. (accto2/refto2)
When App2 also reaches the instance when his access token is expired, he will also try the refresh token grant with the refresh token he already has (refto1) but he will get an authorization error since that refresh token is now expired.
When either of the apps get this error then app needs to realize that someone else has refreshed the token so at this moment the app needs to make a call with the password grant to retrieve the new access token / refresh token pair in action. This time as in the example the App2 will also retrieve the same access token and refresh token pair that the App1 has previously received for his refresh token grant. (accto2/refto2)