How to extend token expiring time if user is not active for a set period using JWT? - jwt

Given an example here for a normal web app.
Traditionally, we use session and set timeout = 30 minutes. if session expires we will redirect user to login. (Expired time will be extended when user/browser interact with web app)
Using JWT, how to achieve that?
I know something about "token refresh", when short-time token expires it will refresh a new one using refresh-token.
But it looks like it don't care about whether user is interacting with web app or not. So as long as refresh-token is alive, the browser can always get a new short-life JWT.
So the question is: How to extend token expiring time if user is not active for a set period using JWT?

When the user interacts with your server then your server can decide to issue another JWT with a new expiration time (not at each request but e.g. 5 min before the current JWT expiration time). If the client receives a new JWT, then it replaces the old one.
When the user does nothing, no new JWT is issued and the JWT will become invalid after the timeout.

If the user is active, then issue a new JWT every time the user enter in the web application and every period of time (for example 1 hour)
If the user is not active but the browser is open, it can request a new JWT to server in background. The token must be requested before expiry time and then replace the token in localStorage or cookie. This technique also can be applied to standalone applications
If browser can not request a new token (closed, not active, etc) then the token will expire and you can redirect user to login in the some way that if server session expires
Check this JWT (JSON Web Token) automatic prolongation of expiration

Related

Does I understand access and refresh token technique for authentication correctly?

After doing some research in using JWT with Access Token and Refresh Token for authentication. I understand this in this way.
After login, return to user Access Token and Refresh Token (using same technique JWT for both).
Saving Refresh Token in Database (one User can have multiple Refresh Tokens for multiple devices).
Whenever user sends a request with invalid Access Token, check Refresh Token and call another api to get new Access Token (doing this in client side). After that, call api to get data again with new Access Token.
If Refresh Token is invalid, deleting its record in database and user must to login again to get new Refresh Token.
Does I understand Access and Refresh Token technique correctly? Please give me some advices. Thank in advance.
Of the 4 steps you listed, some look more or less correct while others do not. I will begin this answer by giving the premise for why refresh tokens were created and what is their main purpose.
Using the JWT pattern with only access tokens, there is a potential usability problem when the JWT token expires. Consider as an example a banking website. When a user logs in, he receives a JWT token with a certain expiry (typically stored under the exp key in the claims section of the token). If the token is given say a 5 minute expiry, then from a usability point of view, it means that the website would have to force the user to manually login every 5 minutes. Obviously, this is not the best user experience, because it means that a user who happens to be in the middle of some business process when the token expires might lose all that work. This is where refresh tokens step in to alleviate this problem.
Using the JWT pattern with refresh tokens means that the user receives both an access and a refresh token. A typical workflow here might be:
After login, return to user Access Token and Refresh Token (using same technique JWT for both). The receiver notes when the access token is set to expire (say 15 minutes).
As the expiry of the access token approaches (e.g. 10 minutes), the UI will send the refresh token to the backend to obtain a new access token (and refresh token). This could be done explicitly, e.g. on a website which displays a popup asking if the user wants to continue. Or it could be done in stealth mode, with a REST call being made under the hood to get the new access token.
For the edge case where the refresh token cannot be used to obtain a new access token, then the very next user action which requires authentication would fail. In this case, the user would have to redirected to the login page. But, as this case should generally be rare, it does not disqualify the refresh token pattern.
I would also point out that storing the access/refresh tokens in the database largely defeats the purpose of the JWT pattern. One major reason for using JWT is that it pushes the user session state out of the application and onto the user. By storing tokens in your database, you are totally making your user sessions very stateful, which has all sorts of potential drawbacks. Consider using the suggested workflow above to avoid doing this.
The way I see it, your refresh token needs to be stored and associated with the device and the user.
Example:
User Logs In in Device A
Call Login endpoint
Validate user is valid
If valid, generate a refresh token associated with the userid & device
id
store required data to your table or storage engine (user_sessions..etc)
user_id | device_id | refresh_token | expires_at
Return the payload with access_token, refresh_token , access_token_expires_at, refresh_token_expires_at
Front-end, store the payload
when consuming a resource, check the following
If refresh_token_expires_at > now then logs them out , show your session is timeout (or you can have a never expired refresh_token.. ex. refresh_token_expires_at can be 0)
if access_token_expires_at > now then call refresh token endpoint along with your payload.
on the refresh endpoint, validate the call and check the refresh token against the data stored.
if refresh token is valid for this user+device, generate a new access_token
return the access_token and its expires_at
If the refresh token is INvalid , return invalid
front end will log the user out.
** in any case, if a refresh token was compromised, it will be only for that particular device/user. A user can then deactivate or remove the device from their list. This action will invalidate the refresh_token on their next refresh call.

OCAPI: How to refresh token after expiration?

Trying to use Salesforce OCAPI from an app.
On the JWT Auth documentation: https://documentation.b2c.commercecloud.salesforce.com/DOC2/index.jsp?topic=%2Fcom.demandware.dochelp%2FOCAPI%2Fcurrent%2Fusage%2FJWT.html
A JWT has a lifetime of 30 minutes. Before the token expires, you must exchange it for a new token if you want to extend the total lifetime.
If a registered user opens the app after 31 minutes and the persisted JWT is expired, then how is the way to refresh it without prompting login screen again? (persisting user credentials is out of the question due to security vulnerability)
As the documentation states, you cannot refresh it if it has expired. You must prompt for the login screen again.
I suggest having your app refresh the token automatically in the background.
You can save exp (the token expiration-time) from payload section in your db, try to check before intiatling new call if its expire then you can use the /customers/auth resource to get new token. You must include the current token in the Authentication:Bearer request header, and specify the customer type as "type":"refresh".

Keycloak refresh token lifespan tied to SSO timeout's

Keycloak refresh token expiry is tied to SSO timeouts. If SSO Session Idle is set to 30 minutes, the refresh token will only work for 30 minutes. Session Idle can only be as large as Session Max, therefore the lowest of both is taken as the max refresh token life. How to specify the Refresh token expiry separately as we have for the access token? If the refresh token expires do we need to get another refresh token. Ideal refresh token expiry time?
A client application uses the refresh token to get a new access token without user interaction. It should do so before, or shortly after the access token expires. It will then receive a refresh token which is again valid for 30 minutes (Keycloak Session Idle Timeout). The client can repeat until the Session Max timespan is over.
As a client don't let the refresh token expire:
If the refresh token has expired, the client needs to direct the browser to the authorization endpoint. To prevent this, your application should use the refresh token when the access token gets invalid. Even better: Schedule a refresh for the time before the access token expires.
Scope offline access
As an alternative, the client could request scope "offline access". In this case, the refresh token lifetime is not bound to the SSO Session idle and Max settings.
For details see https://www.keycloak.org/docs/latest/server_admin/index.html#_offline-access

Sliding expiration session cookie using IdentityServer3

I am using a mix of a browser (Xamarin webview; to initially login and getting an access token that expires in 1 hour) and httpclient (to access my webapi endpoint). When the token expires I request a new one using the /connect/authorize endpoint using a httpclient (with the cookies copied from the webview) to get a new access token.
This works alright as long as the cookies aren't expired.
I've set up identity server to have a sliding expiration of 1 day on the authentication cookie (CookieOptions: ExpireTimeSpan/SlidingExpiration). I thought that this would result (besides getting a new valid token) in receiving new cookies on every request to the authentication endpoint, effectively keeping me logged in. The problem is that the expiry of the initial cookie that I received when logging in using the webview is used. So no matter how many times I access the authorization endpoint, I'm still logged out after a day and I can't get a new token from the authentication endpoint anymore.
Assuming I'm not completely taking the wrong approach, what requests should get me updated cookies (IdSvr? IdSvr.Session? which do I need anyway?) with a new expiry date, so I stay logged in to IdentityServer?
Note: I did take a look at refresh tokens, but these aren't available for implicit flow. And I think I need implicit flow in my case because I shouldn't save a client secret in a distributed Xamarin app. Using the cookies seems like the best alternative.
Note to self (and others): the authentication cookie is the one that's important. For the record: that's the idsrv cookie.
Then the thing that confused me during testing: calling the /authorize endpoint will only return a new authorize (idsrv) cookie when at least half the expiration time has been passed.
This surprises me a bit, because that would mean that:
8:00 log in with sliding exp of 4 hrs (expire time: 12:00)
9:59 request to /authorize endpoint (expected new expire time: 13:59)
12:01 request to /authorize again
The 12:01 request would fail miserably, because the 9:59 call did not get me an updated cookie...
Had I made de second request two minutes later at 10:01, I would have gotten an updated cookie with expire time of 14:01.
Conclusion: sliding expiration seems only be sliding when half the expiration time has passed.

Single Page Application JWT, token refreshing vs long lived tokens

I'm beginning a Single Page Application, and I'm using JSON Web Tokens to Authenticate client side (JS Client with Server API).
In my app, user provides credentials (app auth, facebook, google) and then server checks for user existence and returns a token.
Client JS adds token to each request in order to use the Server API.
When token gets issued, it has an expiry time and a max refresh time. If a set a short expiration time for the token and a "good" max refresh time I get into having to know when to refresh tokens. Best approach I've found so far, is to check on client when the token is being expired (5 minutes before) and then issue a refresh request. Then I'd get a new token. This could be done till max refresh time is reached. Then, user should have to reauthenticate.
Another approach I've seen, is that on server, if token is nearly or has just expired, it gets auto-refreshed and returned to client (which has to detect token change and store it)
But... what is the difference between this and having a single token that is long lived?
Is having a short lived access token which can be renewed with a refresh token tons of times better than having a single long lived access token?
The primary reason to use a short-lived token is to defend against session hijacking, when an adversary, through one method or another, steals session credentials (in this case, the token) and acts maliciously in the victim's session. The shorter-lived the token, the less time the attacker has to carry out whatever malicious activity they have planned.