Why access token has no longer expiry time? - spring

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.

Related

How to increase the expiry date of access token + Spring boot + OAuth?

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.

Can I know in which point we need to validate the JWT expiration?

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.

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

Token based authentication in REST APIs

I trying to implement a token based authentication approach:
Every successful login creates new token.
If user selects "keep me logged in" or the user is using a mobile device, the token is persisted in a Redis database without an expiration date. Otherwise, the token will expire in 20 minutes.
Once user is authenticated, the token is checked from each subsequent request in my Redis database.
I'm wondering how I can identify devices. In case of mobile devices, I can use a device identifier. But how can I identify a browser?
Example: The user logs in using Chrome and selects "keep me logged in". A token is generated and persisted with the browser name in Redis. If the user logs in from Firefox, saves the token and "Firefox" in the database. I save the token in Redis whereas token is created on successful authentication. Is it fine to persist only the token and the browser where the token is being used? Or do I need to persist the IP as well?
Additional question: How to avoid attackers to steal the token from a cookie?
How token-based authentication works
In a few words, an authentication scheme based on tokens follow these steps:
The client sends their credentials (username and password) to the server.
The server authenticates the credentials and generates a token.
The server stores the previously generated token in some storage along with the user identifier and an expiration date.
The server sends the generated token to the client.
In every request, the client sends the token to the server.
The server, in each request, extracts the token from the incoming request. With the token, the server looks up the user details to perform authentication and authorization.
If the token is valid, the server accepts the request.
If the token is invalid, the server refuses the request.
The server can provide an endpoint to refresh tokens.
How to send credentials to the server
In a REST applications, each request from client to server must contain all the necessary information to be understood by the server. With it, you are not depending on any session context stored on the server and you do not break the stateless constraint of the REST architecture defined by Roy T. Fielding in his dissertation:
5.1.3 Stateless
[...] each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. [...]
When accessing protected resources that require authentication, each request must contain all necessary data to be properly authenticated/authorized. It means the authentication will be performed for each request.
Have a look at this quote from the RFC 7235 regarding considerations for new authentication schemes:
5.1.2. Considerations for New Authentication Schemes
There are certain aspects of the HTTP Authentication Framework that
put constraints on how new authentication schemes can work:
HTTP authentication is presumed to be stateless: all of the
information necessary to authenticate a request MUST be provided
in the request, rather than be dependent on the server remembering
prior requests. [...]
And authentication data (credentials) should belong to the standard HTTP Authorization header. From the RFC 7235:
4.2. Authorization
The Authorization header field allows a user agent to authenticate
itself with an origin server -- usually, but not necessarily, after
receiving a 401 (Unauthorized) response. Its value consists of
credentials containing the authentication information of the user
agent for the realm of the resource being requested.
Authorization = credentials
[...]
Please note that the name of this HTTP header is unfortunate because it carries authentication data instead of authorization. Anyways, this is the standard header for sending credentials.
When performing a token based authentication, tokens are your credentials. In this approach, your hard credentials (username and password) are exchanged for a token that is sent in each request.
What a token looks like
An authentication token is a piece of data generated by the server which identifies a user. Basically, tokens can be opaque (which reveals no details other than the value itself, like a random string) or can be self-contained (like JSON Web Token):
Random string: A token can be issued by generating a random string and persisting it to a database with an expiration date and with a user identifier associated to it.
JSON Web Token (JWT): Defined by the RFC 7519, it's a standard method for representing claims securely between two parties. JWT is a self-contained token and enables you to store a user identifier, an expiration date and whatever you want (but don't store passwords) in a payload, which is a JSON encoded as Base64. The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token, you could persist the token identifier (the jti claim) and some metadata (the user you issued the token for, the expiration date, etc) if you need. To find some great resources to work with JWT, have a look at http://jwt.io.
Tip: Always consider removing old tokens in order to prevent your database from growing indefinitely.
How to accept a token
You should never accept expired tokens or tokens which were not issued by your application. If you are using JWT, you must check the token signature.
Please note, once you issue a token and give it to your client, you have no control over what the client will do with the token. No control. Seriously.
It's a common practice to check the User-Agent header field to tell which browser is being used to access your API. However, it's worth mention that HTTP headers can be easily spoofed and you should never trust your client. Browsers don't have unique identifier, but you can get a good level of fingerprinting if you want.
I don't know about your security requirements, but you always can try the following in your server to enhance the security of your API:
Check which browser the user was using when the token was issued. If the browser is different in the following requests, just refuse the token.
Get the client remote address (that is, the client IP address) when the token was issued and use a third party API to lookup the client location. If the following requests comes an address from other country, for example, refuse the token. To lookup the location by IP address, you can try free APIs such as MaxMind GeoLite2 or IPInfoDB. Mind that hitting a third party API for each request your API receives is not a good idea and can cause a severe damage to the performance. But you can minimize the impact with a cache, by storing the client remote address and its location. There are a few cache engines available nowadays. To mention a few: Guava, Infinispan, Ehcache and Spring.
When sending sensitive data over the wire, your best friend is HTTPS and it protects your application against the man-in-the-middle attack.
By the way, have I mentioned you should never trust your client?
Once server is receives the request from the client, it contains the User-Agent. This attribute will help us to identify the client.
Please refer this link: How do I detect what browser is used to access my site?

Spring security OAuth2 - how to disable access token expiry?

I have requirement where in client makes API calls using the access token. Generating access token is one time job and I will be providing the access token to the client.I believe, the spring security has a expiry on the access token on expiry of which need to pass the request token to get a new access token. Is there a way to disable the expiry of access token, which enables the API access with single access token always?
According to the API docs, you can set a zero or negative value for the access token validity if you don't want the token to expire.
Note that this will be overridden if you have set a specific value for the client.

Resources