0
votes

I have a central 'hub' containing the data for multiple organisations, each of which contain multiple users. Organisations and users are grouped together, along with 'client_credentials', under a 'Project'. The user can authenticate using the 'password' grant type, and they obtain access & refresh token, as per the OAuth2 spec. Both are JWT.

The issue I have is correctly attributing the refresh token withe the relevant user in the 'correct' way so that I can issue a JWT access_token with the correct content.

When requesting the original tokens, I pass and validate both the client credentials and the user's username/password. Two identical (other than expiry time) tokens are generated containing the user_id and other bits. One for access, one for refresh.

So when validating the refresh token, I see (unless my understanding is wrong) a few ways of making this happen:

  • On the initial request, store the refresh_token against the user's database record, and do a lookup based on the association with the client credentials as well as this stored token. OR:

  • Generate the new access token from the unpacked refresh_token, just with a new expiry date - meaning I don't need to actually persist these things.

In some ways, the first approach seems ok, apart from my reluctance to perform database queries using any type of password/token, as typically I'd never index these fields. And in other ways, the second approach seems ok as it doesn't actually require me to persist sensitive tokens unless I explicitly want to mark it for revocation - but it does somewhat require that the access_token and refresh_token are kept pretty much the same.

Any steer on which is the 'correct' approach, or does anyone have any alternatives?

1

1 Answers

0
votes

Using the Password Grant type, you are generating/receiving two tokens: Access Token and Refresh Token. These tokens should be stored securely either in a memory table in your application or in a database. If you are using an autoscaling or fault-tolerant design, you need to use a database.

Once you have the tokens, you create an opaque random number (usually 128-bit, sometimes 64-bit), let's call it AUTH_ID. The tokens plus expiration are indexed by this AUTH_ID. You store the AUTH_ID in the client browser's session or return with the tokens. If there is a design already in place, then you will need to create a method to search the database to match the tokens passed to you. If the user does not actually require tokens, give them the AUTH_ID instead.

When the client makes a request to you, extract the AUTH_ID from the client session and lookup the tokens. If a token will soon expire, refresh it and store the new token. Then continue with the client's request.

The contents of a Refresh Token is implementation-specific. This means that if you want to rely upon information about a Refresh Token (or an Access Token) you must store that information alongside the token. Some tokens are Signed-JWT, some are Opaque.