1
votes

I have a system with an REST API. The users of the REST API should be able to authenticate using OpenID Connect over Oauth2. The system itself has its own permission system. I need to map the IDPs user towards my local permission system. I'm thinking of saving the openid scope sub key in the local database as a unique user identifier.

But which token should I return to the user in the API. Should it be the oauth2 access id or token_id from the OpenID Connect layer, or perhaps both?

So I see these alternatives for the end-user of the API:

Authorization: Bearer <access_id>
Authorization: Bearer <token_id>
Authorization: Bearer <access_id>
TokenID: <token_id>

Without keeping the token_id/access_id in the system I need to get this from the client per API request. The token ID contains the JWT claims (sub) so I need this to validate what the client can do in my system.

Do I need to store any of the ID's below in my local database in order to validate API requests, or should the user provide it?

  • Refresh token?
  • Access token?
  • Token ID?

I'm basically after authentication and user identification. I'm not after getting access to any external resources other than this.

And last question. Do I need to validate the access token every request towards the IDP or can I cache it? Do I need to validate both access token AND token id when using OpenID Connect?

Edit:

My system itself has an REST API and its own permission system. The permission system uses user IDs given by an any authentication system that uses OpenID Connect. The first user is manually added to the permission system.

Thought flow:

  1. User of my system requests https://mysystem/login
  2. User get redirected to https://idp/auth
  3. IDP redirects successful login to https://mysystem/callback My system get user id (sub) and email from token id JWT.
  4. And back to the user with a access token (not OIDC token id).
  5. The user can now perform: curl -H "Authorization: bearer access token" https://mysytem/some/resource
  6. Mysytem get this request from the user but don't know how to map access token to the user ID in the database w/o asking IDP for the user ID.

I want to use an external IDP to let users login, not to get access to resources from 3rd party systems.

1

1 Answers

1
votes

UPDATE

An access token DOES have a user id - see step 14 of this write up. Why do you think it doesn't?

The one exception to this rule is when there is no user involved - for app to app communication (eg client credentials flow). But you are not using that.

ORIGINAL ANSWER

You should just send the full access (bearer) token from UIs to APIs - and you should not need to store token details in your database.

When migrating to an OAuth architecture you will store user data in 2 places:

  • Your normal product database - which often includes roles and user rights
  • The Authorization Server - which generates a unique user id

It is fairly common to store the unique user id in product data for correlation and tracking, as you suggest. After login your APIs will often need to authorize based on product data.

A couple of my blog posts cover these topics in more detail:

My blog also links to sample code that ties these concepts together.