Are refresh token still valid even if they are not stored in a database anymore? - access-token

Lets put on this situation.
User logs in, he gets a refresh token and an access token
Access token expires, user gets a new one by refreshing it, and the refresh token in the database assigned to the user is overwritten by a new one.
The old refresh token, is now not stored in the database, but is it still valid? Since the expire date is in 7 days.
If an attacker managed to get access to that refreshtoken, will he still be able to generate new access tokens by verifying it with the refresh? I guess he needs to obtain the secret for this anyway.
Is a solution to avoid this simply checking if the refreshtoken is assigned to an user in the database during the refreshing proccess?

Related

Laravel Passport new access token generated on login

I've gotten Laravel 5.6 set up with Passport and working with the Implicit grant.
The only thing I don't understand is, every time I hit /oauth/authorize, a new access token is generated in the database. If there is no existing token, it will prompt the user to authorise the request and then create a new access token that expires in 1 year.
If a token already exists and is valid (e.g. user already authorised the request before), it logs the user in directly but also creates a new access token (leaving n+ tokens available instead of invalidating the previous tokens).
This means that my users will see duplicates in their 'authorised applications' screen, which doesn't look right.
Is this normal? Should I be doing something more when logging out instead of just deleting the token locally?

Refresh Token gets revoked with Access Token in Laravel Passport

I am using laravel/passport password_grant for authentication. The whole generating access_token and refresh_token process is working fine. Now I am trying to use laravel passport token events to revoke old tokens.
I referred to this post for the process -
https://laracasts.com/discuss/channels/laravel/laravel-passport-revoke-and-prune-event-listener-is-not-doing-anything
This works... But when refreshing an access token using the previously provided refresh token, a new access token is being created and also a new refresh token being is created. Eventually, while revoking the old access token, the old, not expired refresh token also gets revoked.
But I think, the refresh token must be revoked only when it has expired.
And also when I remove the EventListeners from the App\Providers\EventServiceProvider $listen array, the revoking mechanism still works.
It's like even pulling out the plug the light bulb is still on.
How to solve this issue? Or am I wrong with the concept somewhere?
But when refreshing an access token using the previously provided refresh token, a new access token is being created and also a new refresh token being is created.
That's basically what makes refresh tokens prevent MITM attacks (to some extent). If someone intercepts your communication and finds your access token, they can impersonate you for as long as it lives. But if they intercept your request to refreshing your tokens, only one of you (the user and the attacker) can use it because it's revoked once used. If you get to use it first, it becomes useless to them. If they use it first, you'll be logged out because your old tokens will be revoked. If they can intercept all your requests - and keep finding your new access tokens, you need to reconsider your security setup.
From RFC6749 section 1.5. Refresh Token under Figure 2: Refreshing an Expired Access Token:
(H) The authorization server authenticates the client and validates
the refresh token, and if valid, issues a new access token (and,
optionally, a new refresh token).

Django REST JWT Refresh

Implemented Django REST and authentication using JWT.
For JWT token we have to refresh it before it expire.
After expired JWT wont give new token.
For my mobile device I need to refresh the token every 10 mins (JWT_EXPIRATION_DELTA).
and if user is not active for more than 10 minutes, then I need to ask to login.
Is there any way that I can refresh the token even after JWT token expired. (we can limit the time to refresh as 2 day)
Whats the best way to handle this behavior in Mobile.
Thanks.
Refreshing tokens in django-rest-framework-jwt
The django-rest-framework-jwt (v. 1.11.0) does not support "Refresh Tokens" as described for example here. It only supports refreshing non-expired tokens; It makes easy to implement a sliding expiration window with width of JWT_EXPIRATION_DELTA. For example, with settings
'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300),
'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
user cannot be inactive for more than five minutes in order to stay logged in (docs).
Real Refresh Tokens, please?
It is possible to implement the "Refresh Tokens", which are very long lived ("never expiring") tokens, stored in a database, just like in conventional "HTTP Sessions & SessionIDs". This is actually already been implemented for the django-rest-framework-jwt in django-rest-framework-jwt-refresh-token. Another possibility is to use django-rest-framework-simplejwt which also implements the JWT with Access and Refresh Tokens (full example at Medium).
But.. why?
Compared to using only Access Token JWT's, using Refresh Tokens makes possible to revoke access after the Access Token is expired. Refesh Tokens make it possible to have very long ("lifetime of a mobile device") lasting tokens. One may ask why shouldn't you just stick with sessions (sessionid in a Cookie, and session data in database table), if you are creating collection of Refresh Tokens in a database, and accessing that. Using an Access token with expiration time of one hour will mean that database must be accessed once per hour (instead once per PUT/POST request when using "traditional" sessions). In addition, you gain all the usual benefits of JWT tokens (ease of use in microservice network, for example).
You can use refresh tokens, as defined in Oauth2.0
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires,
After a successful login, issue a refresh and an access token. While a access token expires shortly, a refresh token is long lived. Store it securely, and use it to issue new access tokens when the current one expires

VSTS API Refresh Token Expires

I'm using the VSTS REST API. I use the refresh token, as instructed, to refresh the access token. This morning, the refresh tokens stopped working. Do they expire? If the access token and refresh token have both expired, how do I proceed? I can't find anything on this.
For reference: https://www.visualstudio.com/en-us/docs/integrate/get-started/auth/oauth#refresh-an-expired-access-token
Yes, the refresh token will be expired, you need to send request to re-authorize to get access token and refresh token again (your previous steps to authorize).
The previous access token and refresh token have been expired after get new access token.
I manage the team that implements this flow. The answer from #starain is correct and this flow is described in detail in the OAuth 2 specification. Your observation that the refresh token is invalidated so frequently #scottndecker is not consistent with the implementation. A refresh token in our system has a default lifetime of one year. The token can also be invalidated manually by users. We obviously must honor the user's right to revoke a previously granted authorization. If you want to share some more information we can certainly look into this behavior.
Seems that when the auth.token expires (after one hour), the auth.refreshtoken become invalid too? What is the auth.refreshtoken purpose then? When I decode the auth.refreshtoken on jwt.io, it should expire sometime in 2020. (Now it's 2019).
While the auth.token is valid, I can refresh and get a new token. So is the idea that I should setup a job that refreshes the token within one hour?
The documentation claims:
If a user's access token expires, you can use the refresh token acquired in the authorization flow to get a new access token. This process is similar to the original process for exchanging the authorization code for an access token and refresh token.

Refresh Tokens - Server Side Storage And Revoking For Multiple Clients

I'm getting started with token based authentication using the ASOS (AspNet.Security.OpenIdConnect.Server) framework.
I've got the access token generation and retrieval done and am now moving on to the refresh token bit.
My questions are:
How should I store the refresh token server side?
Should I just store the clientID and the hashed and salted refresh token in a database (Along with utility fields, such as an expiration date)?
What is the expected behaviour if a user of my API has a single clientID and secret, but performs many calls concurrently (Suppose they want to scale out the client on their end across multiple machines to get better throughput for example).
Specifically, I mean what if 1 of the client's access tokens expires, but their refresh token has also expired?
Of course they can go to the token endpoint to get a new access token and refresh token at the same time, but then what about the other instances for that clientID? Assuming that their code is identical (i.e. they don't share knowledge of the refresh token), each instance will also go on to request a new access and refresh token.
If you store a single refresh token for a clientID, you'll end up excessively requesting refresh tokens, potentially every time the access token expires, which would be undesirable.
If you store multiple refresh tokens for a client, how many is a sensible number?
Also, what is the common process of revoking the refresh tokens?
Is it as simple as just deleting it from wherever you're storing it?
Thanks.
Should I just store the clientID and the hashed and salted refresh token in a database (Along with utility fields, such as an expiration date)?
The approach I recommend is to use the ticket identifier attached by ASOS to all the tokens it creates. You can retrieve the refresh token identifier and the expiration date from the SerializeRefreshToken event via context.Ticket.GetTokenId() and context.Ticket.ExpiresUtc.
Note: the default identifier is a GUID but you can replace it using context.Ticket.SetTokenId("token identifier").
Specifically, I mean what if 1 of the client's access tokens expires, but their refresh token has also expired? Of course they can go to the token endpoint to get a new access token and refresh token at the same time, but then what about the other instances for that clientID?
It really depends on your application requirements and how you implement that. You're free to consider refresh tokens as completely independent or, conversely, interdependent. This logic would usually take place into HandleTokenRequest.
Also, what is the common process of revoking the refresh tokens? Is it as simple as just deleting it from wherever you're storing it?
If you use the default token format (more than recommended), refresh tokens will be considered valid until they expire. It's up to you to check whether the token has been revoked from HandleTokenRequest by making a DB lookup (you can get the refresh token identifier using context.Ticket.GetTokenId())

Resources