Get authorization from remote API

Hi,

I’m using OIDC for authentication, and I want to add permissions of users to their access token.

My problem is that our permissions are managed by a dedicated application, and that we can recover them by an API.

So : How can I add authorizations to the claims of an access token, by getting these authorizations from a remote API?

Regular access tokens should really only contain claims about the user and thinks like roles and scopes, not direct permissions. When you say permissions do you mean RBAC type permissions or something else?

1 Like

When I say permissions I mean ‘fined-grained authorization’, i.e. roles associated to a group of resources. For example: “Manager for Europe”.

Should I code a custom mapper for this?

I would probably suggest looking at authorization services instead of trying to add it directly to the access tokens. Problem is that access tokens have a limited size, and with fine-grainted authz it’s hard to manage the size in terms of scoping the tokens. As such it may be better to use authorization services.

You mean Keycloak native authorization services? How can I link that to a remote authorization API?

I have tested two options to perform this

  1. Wrap the /token and /token/introspect endpoint to add custom content in the access token. It is not obvious and needs a relatively good understanding of the oidc protocol.
  2. Perform a custom authenticator that is added at the end of the authentication workflow that will, according to the connected user perform the call to the API and add user attribute or session notes (using javascript adapter and npm package keycloak-rest-authentictor) .Then the normal mappers will pick the user attributes or sessions notes and add these as claims in the tokens.

I can show this in more details if you are interested

Hello guenoldc,
I am very interested by having more information about the two options you have experimented. I have the exact same need where all the user roles are managed in a custom remote api and I need to enrich the access token with those roles.
So thank you for any help with this.

Hi Dypsok,

In the first scenario, we built a NodeJs service that on one end exposes the /token, /token/introspect, /certs endpoints to intercept the calls and forward them into keycloak (like a custom reverse proxy if you wish) but the responses are intercepted, analysed and completed by the customised access token and introspecting result. In your case, your API must be called and the result used to complete the token content. If the jwt is needed, it cannot be signed by Keycloak private key, so the NodeJs service must holds its own private key. Then the /certs endpoint should return the public key of the service aggregated with the public keys of keycloak.
In addition, once you have this done you should wrap keycloak behind a real reverse proxy (like nginx) and make it redirect the …/realmname/[token* or certs] to your service and the others endpoints to keycloak directly. Then from the client perspective, the nginx becomes the real IDP server.

In the second scenario we take a very different approach and uses the Keycloak enrichment mechanism :

  • The keycloak authorization workflow enables to add custom authenticator that can perform actions on the keycloak data model. I have published this in the form of a library that I described at https://medium.com/application-security/how-to-create-a-keycloak-authenticator-as-a-microservice-ad332e287b58.
  • Then in the custom implementation of your authenticator you would call your custom API and use the result to feed the keycloak data model - such as the user attributes and/or session notes
  • Then, in keycloak mappers you can use these fields (user attributes and session notes) to feed the keycloak tokens

The choice between the 2 options is, in my opinion, based on whether you consider Keycloak a long term choice (scenario 2) or not (scenario 1). So use the scenario 1 mainly if you need later to change your IDP technology or be as much as possible independent from version changes.

I hope I have clarified things for you, if you need more, maybe we can have a longer chat and share some code (that I cannot publish) or co-construct a prototype