We have a restful API developed on spring-boot V1.5.7 and it is secured by OAuth with "password" grant type. We are using only access token, the refresh token is not being used. The validity of access token is set to 15 mins. Initially, we hit the token endpoint and get the token and consuming the services. Though the services are being consumed very frequently the access token is getting expired after 15 mins. What we are expected to do is, when the services are not being called for 15 mins only then the token should be expired.
Can anyone please help me on this?
Looks, First we need to know Why we used access token?
Access token is used for accessing protected resource. It has a validity periods say for example 1min, 10min etc. After that time, token becomes invalid. To get a new valid token you should use refresh token.Though you can get a completely new token using your username and password. Even if you invoke any api within the expiry time though, the token invalid after the expiry time. If you don't invoke any api within the expiry time, token becomes also invalid. This is expected behavior.
Why this is expected?
Suppose you get an access token from server and access protected resource from server with access token. Somehow man in the middle get the token by sniffing packet. Then intruders can get easily access the resource as you can and as much time he want's. So technically we can say that, your account is being hacked.
To prevent this attack, you should define a token validity periods that would be suit for your use case. So this is more secure than previous.
I would strongly recommended that allow refresh token for your system.
However You can also configure your system to reuse the token. This link may be a help.
You can use OauthRestTemplate (if you don't want to write your own logic) which will fetch a new the access token (using refresh token) after it is expired. There is no reason to not use refresh token if you are planning on using OAuth in your application.
Related
I am trying to implement Oauth2 with Jwt in my Application. One doubt I am having is why do I need to have lesser expiry time to access_token and a longer expiry time to refresh_token.
What I mean to say is I can have an access_token with a longer expiry time and I would protect access_token like I am protecting the refresh_token, there is no need to refresh_token only. Does that make sense?
So if I am ignoring refresh_token from my application, would I face any usability issue or security issue?
See RFC 6749:
1.5. Refresh Token
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, or to obtain additional access tokens
with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource
owner). Issuing a refresh token is optional at the discretion of the
authorization server. If the authorization server issues a refresh
token, it is included when issuing an access token (i.e., step (D) in
Figure 1).
A refresh token is a string representing the authorization granted to
the client by the resource owner. The string is usually opaque to
the client. The token denotes an identifier used to retrieve the
authorization information. Unlike access tokens, refresh tokens are
intended for use only with authorization servers and are never sent
to resource servers.
I am quite new to JWT based authentication. And im quite confused about the refresh token mechanism. In my case, I have designed my application as,
1. User will login to the application, and when the login is successful then it will go to the authentication server and sign a jwt and will pass it to the client.
2. And then the client will store the refresh token and the short lived token in the local storage
3. Once the resource server is called the token will be sent through the header. and will get validated.
My question is, in which point should we request another token using the refresh token mechanism. Should we check whether the short lived token is invlaid before sending the request to the resource server. or should we get a new token once the validation fails in resource server? or is there any better way to handle this?
A Refresh Token is a special kind of token that can be used to obtain a renewed access token —that allows accessing a protected resource— at any time.
Although Access Tokens can be renewed at any time using Refresh Tokens, they should be renewed when old ones have expired, or when getting access to a new resource for the first time. Refresh Tokens never expire OR have very long expiration time.
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
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.
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())