-1

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?

Mark G
  • 85
  • 1
  • 5

1 Answers1

0

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.

John Hanley
  • 74,467
  • 6
  • 95
  • 159
  • Ok, so basically storing the tokens is the typical approach to this problem as opposed to just sending them out and relying on your ability to decode them for the required information? – Mark G Oct 30 '19 at 16:15
  • You should store tokens, usually in a database. Unless your design requires the client to have tokens, sending tokens (specifically the Refresh Token) to the client is a bad idea. You may or may not be able to decode the tokens as this is implementation-specific and you cannot rely upon this unless a vendor's specification says otherwise. An Identity Provider can use opaque tokens, Signed-JWT or anything they feel like. The exception is Identity Tokens. – John Hanley Oct 30 '19 at 16:42