What happens with old jwt token in vert.x? - jwt

Does it just expire at the same time when the new one was generated or it still lives for some specified period?

JWTs by design can't be revoked. A JWT is valid until it expires, which is the date from the exp claim. There are solutions where you can blacklist JWTs and treat them as expired, but I don't think that vert.x implements such a solution.

Related

How to prevent log out users when changing JWT secret?

I am using a JWT token implementation of this https://jwt-auth.readthedocs.io/en/develop/quick-start/
I need to update the secret key and is there a way to update it without logging out every user? I presume it's not possible to reuse the old token once my secret key is changed. So all my users will be logged off and need to log in again. Is there any way to go around this?
If not, if for security reason, I need to update the secret monthly, that will be pretty troublesome to ask my user to re-login monthly.
Thanks!
If you change your keys it's correct to invalidate all the tokens signed with the old ones as they are to be considered expired.
It's a good practice to let the token expire as well after a certain amount of time. Usually you implement a mechanism based on two tokens, access_token with an expiration of 1h (usually) and a refresh_token with a longer expiration (usually 24h). The second one is used to renew the first one. When the second one expires, the user has to be considered logged out.
What you need is to implement a refresh token mechanism. You can implement it from scratch, for learning purposes, or you could just implement OAuth 2.0 protocol, since it's a flow that it already supports. There are lots of libraries both for server side and client side implementations
https://oauth.net/

DocuSign: set expiration in JWT Token - always get access token with one hour expiration

We are developing an integration with DocuSign. We use embedded signing and JWT authentication.
We received information from DocuSign Partner Solutions team that in JWT authentication, the expiration of the access token can be set by us to a long period of time.
based on that information, I designed the solution so we manually do the JWT authentication flow: get user consent, generate JWT, set expiration to one year and use it to obtain a long expiring access token.
now we went out of sandbox to production. We are testing the solution against a 30 days trail production account. We got user consent. I generate JWT and set expiration to various periods (one day, one month, one year) but I always get an access token that is good for one hour only.
PS, I went through the official documentation which states this about JWT exp property:
Defaults to one hour from the value of iat, and cannot be set to a greater value.
I wanted to know if anyone was able to generate long expiring access token out of JWT in DocuSign
The maximum grant time for access tokens received via the DocuSign OAuth JWT Grant flow is 1 hour.
The maximum grant time for access tokens received via the DocuSign OAuth Authorization Code Grant flow is 8 hours.
Good news for your application is that it is easy to obtain a new token via the JWT Grant flow: just re-run it within your app when the token that you have is about to expire or has expired.
No interaction with the user is needed since they have already provided consent (a one-time operation).
Note that the JWT Grant flow can fail, especially if the user has withdrawn their consent. Be sure to test this situation.
I'm sorry that you were given incorrect information.

How to handle JWT expiration

I have a question on "make the browser send out a request to exchange for a new token at the sixth day. Accordingly, on the server side, create a restful API named /token/extend which will return a new token if given a valid token."
Let's assume that I implement this concept. When token is about to expire, we will generate new valid token if old valid token is provided.
Now, let's assume, Hacker gets the token. He uses this token to communicate with APIs. Hacker communicates for 6 days. On 6th day, our "/token/extend" API will generate new token for him so he can communicate for another 6 days, and probably forever. Will this situation occur? or Am I missing something here?
The general way you would force your users to obtain a new token after 6 days would be by simply setting the exp field (expiry) in the claims of the JWT to expire after 6 days. The exact mechanism by which users would use to obtain a new token depends on your implementation.
The most basic implementation would be to just let the incoming request on the sixth day to fail, forcing the consumer of the API to redirect to the login page. From there, the user would have to login again to obtain a new valid JWT. A more elaborate method would use refresh tokens. With this approach, when the user first logs in, he would receive an authentication token with a 6 day expiry (as before), but would also receive a refresh token which would expire a little bit later. On the sixth day, when the user tries to access a service, the request would again fail. However, in this case, the consumer (e.g. a website or mobile app) could take the refresh token and request a new access token under the hood. This would be a more seamless way of handling the mandatory 6 day expiry. Note that with the refresh token approach, the user might never know about the 6 day expiry.
Regarding your concerns about hackers obtaining other people's tokens, you should mostly just forget about this. If someone stole your wallet, there is all sort of havoc he could do to you, e.g. using your credit cards, stealing your identity, etc. The same could happen with a stolen/sniffed JWT. The best practice here is to just make sure you are using two-way SSL for all communication, and also encourage your users not to use your services in places like Internet cafes.

JWT and blocking users

JWT is a stateless authentication mechanism as the user state is never saved in server memory.
How to invalidate the token if administrator blocks the user for some resons?
JWT is not an authentication mechanism but a token format. Since JWT are self-contained, you CAN use them for stateless authentication. However, this does not mean that your authentication mechanism MUST be stateless (although there it has its benefits).
There are several options for handling user lockout / revoking authorization:
Do a lookup of the user in every request after validating the JWT to see if the user is locked out
Access tokens are supposed to be short-lived, so you can look up the user the next time a new access token is requested (e.g., using a refresh token) and then refuse issuing a new access token
Alternatively, you can blacklist all tokens issued for a specific user by storing their jti in a database. See also: https://auth0.com/blog/denylist-json-web-token-api-keys/. EDIT: As pointed out in the comments, while not strictly stateless, this approach is still efficient, because a blacklist only needs to store blacklisted tokens for the duration of their lifetime, and lookup should be highly efficient.
You can look up the user identified by a specific JWT every N requests or whenever X percent of the lifetime of the JWT has passed rather than doing it in every request.
None of these approaches is entirely stateless. In general, stateless authorization is not possible if you want it to be possible to revoke authorization. If you want your tokens to be entirely stateless, you should make sure their lifetime is as short as possible, and issuing a new token is not stateless.

JWT and one-time tokens?

I'm in the process of rolling my own JWT token auth, however, I would really like it to be a one time-token – so once it's used, the server generates a new token and the client will have to use that token during the next request/call.
However, it has come to my understanding that JWT is supposed to be 'stateless' – but with the approach of a one time token, I guess I would need to somehow store the valid tokens, since the token will be refreshed once it's used. Or is there any way to avoid storing a value on the server, and still be able to create one-time tokens?
The two main reasons for why I don't want to store any value is first of all scalability (sure, I could have cache-server inbetween to store the values, but it would be nice if that wasn't required), secondly, JWT is supposed to be stateless from my understanding, which it wouldn't be if I need to store a value on the server to be able to validate the token.
Any ideas?
Use the user's current password's hash for signing the JWT token, in this way all tokens generated before a successful password change would get invalidated the next time. I got the idea from here https://www.jbspeakr.cc/howto-single-use-jwt/.
Solutions exist, of course.
As with any distributed system (you mentioned scalability) you have to choose between availability and consistence.
You choose availability. In this case you could maintain a list of already-used tokens that you replicate in a eventually consistent manner between all the endpoints. For example when a token is used the respective endpoint send that token to the other endpoints in the backgound. There is however a (short) time frame when that token can be used a second time by another endpoint until that endpoint is updated.
You choose consistency (you won't allow a token to be used multiple times whatsoever). In this case you use a central database with already-used tokens and you check that database everytime you need to perform an action. Scalability? You could use sharding on the token and have n databases, each one being responsible for a tokens subset.
It depends on your business what solution fits best.
Not really no, a JWT token is valid if it hasn't expired and the signature is correct, commonly people will keep a DB of blacklisted tokens which are usually ones where people have logged out etc.
The only sensible way I can think of is give them a short expiry time and maintain a list of tokens that have already been used, you'd then periodically remove the ones that subsequently expire from the DB.
There are actually some DB's that have a TTL on records (dynamoDB, mongodb) so you'd just put the tokens in and set a TTL for when the token expires.
Update 2022
Just to be clear JWT tokens AREN'T stateless they have claims that, as long as they're signed by the right private key - give you a stateful piece of data that can be reissued by your API to reflect the current state of the user.
You'd just need to handle token re-issue on the consumer.
Like others have mentioned, it depends on your business case. Password resets links can be like mentioned on https://www.jbspeakr.cc/howto-single-use-jwt/.
If you have the Single-Use & Single-Auth scenario, where you might want to invalidate any previously used and unused token, you can store a single nonce and update it on every new token request and also when its used.