I have the need to provide some information to a third party product.
The third party product manages the user base on it's systems and assigns it's users a Role.
When a request comes in for getting a token - I need to bind this Role to the token.
I would then later use this Role to verify if the user can get access to some resource in my back end api.
From my current understanding it seems to be a Client Credentials Grant (authorise the client app). But how do I capture the Role?
Or should I be using a different oAuth 2 Flow?
- It would be ideal if the request for token can pass the Role to me somehow as part of the oAuth 2 Process.
I think ....
Here's a hands-on lab exercise that shows you how to do Password Grant with Apigee Edge. And here is the Proxy that dispenses tokens via PG.
OK, now, beyond the grant type...
The real question you asked was "how can I attach the user role to the token?" And the answer is "custom attributes". There are two moments
At the time of token generation.
When you use the OAuthV2/GenerateAccessToken policy, specify a custom attribute to hold the role. It might look like this:
<Attributes> <Attribute name='authenticated_user' ref='userauth.user.email' display='true'>UNDEFINED</Attribute> <Attribute name='grant_type' ref='request.formparam.grant_type' display='true'>UNDEFINED</Attribute> <Attribute name='user_groups' ref='userauth.user.groups' display='true'>[]</Attribute> </Attributes>
Look in the sample token dispensing proxy that I referenced above for the full example policy configuration. It uses "user groups" but the idea is the same. This group or role information is sent back by the IdP that your token dispenser uses to authenticate the user.
I have struggled with this use case myself so i thought i'd put my thoughts here and see if they stand the community challenge.
I have no doubt in my mind that Authorization Code Grant should be the preferred way to go for third party integrations. But i don't think it is always practical/feasible in the scenario you listed.
Imagine a scenario where a trusted partner hosts a website and uses API's from multiple providers to create their home page experience. Each of them followed the Authorization Code Grant approach, this would basically mean that the end user would have to login multiple times (for each provider) before they land on the home page. That would lead to a very crappy user experience.
So, i think when
Client Credentials would be the preferred approach.Yes, the grant type was created for Service-Service accounts but this is exactly that scenario because your API does not know the end user and cannot validate the end user. As far as your API is concerned, a real live user does not exist. Only a role does.So, the client could use a service account to fetch data from your API and somehow propagate the end user's role context.
The client(Third Party Product) would create a JWT to embed user claims. This token could then be propagated to API Providers who can verify the token and extract the claims
Dino's suggestion on attaching the Role during the Access Token Generation process(extracted from the JWT claim) would be perfectly valid if the Third Party product requests an access token per user. I am not sure if it should. Your system doesn't know the user, it only knows the user role. You could perhaps create an access token per role but then you are forcing the client to keep track of role-access token mappings. It's easier to track the access token for the user.
Personally, i would prefer that the JWT token is embedded in the Data Request Call (not in the Generate Token Call), a shared flow would extract the role and perform the entitlement checks required for data access.
fyi, there is a proposed standard for JWT Bearer Authorization Grant Type
User | Count |
---|---|
1 | |
1 | |
1 | |
1 | |
1 |