4

Objective: I am trying to add authorization details to the JWT using a custom mapper for Keycloak, so that when a user logs in using the login page, his token will also contain all the permissions that are applicable. As an example, here's the following code (decoded from the JWT):

"authorization": {
    "permissions": [
      {
        "scopes": [
          "edit",
          "buy"
        ],
        "rsid": "af23b104-1d7e-41ab-7600-6d5bb405ad8e",
        "rsname": "Custom Resource"
      }
    ]}

To be more specific, I'm trying to obtain a similar result as if using grant_type=urn:ietf:params:oauth:grant-type:uma-ticket, but directly from the default Keycloak login page.

What I tried: I tried making a custom mapper based on this example: https://github.com/mschwartau/keycloak-custom-protocol-mapper-example

I looked in the base code of Keycloak, but there doesn't seem to be any way to include authorization data in the tokens using the default behaviour. From what I could find, the data might be in the KeycloakPrincipal, but I am not sure if this is true, because there doesn't seem to be a way to obtain that. I might be mistaken, though, since I'm not very experienced with Keycloak.

As a side note, using the grant_type=urn:ietf:params:oauth:grant-type:uma-ticket in a rest call works, but it is not an acceptable solution, unfortunately.

C Smith
  • 123
  • 1
  • 7
  • 1
    Same question for me. Currently I need to make 2 separate calls to KC, one to authenticate, the other to authorize. I'm using **spring boot** autoconfigure dependency, I guess I could live with 2 calls if I have the ability to update the token with authorizations inside to the **KeycloakSecurityContext** – Rwanou Oct 02 '19 at 15:42

1 Answers1

0

TLDR; This can't be done, Keycloak doesn't let's you and/or doesn't have a mechanism implemented for this.


This can't be done as the token containing the permissions ie RPT token, is actually provisioned by Keycloak with invoking the authorization endpoints, and that in turn requires a user access token in the first place.

This is how it's currently done and implemented - so what you can actually do is, implement on your client app a mechanism for fetching that RPT upon login. You'll have to make two requests to Keycloak, one obtaining the JWT and the other one obtaining the RPT.

But all in all, this isn't encouraged, as the general idea is not to return all permissions when a user logs in, but to actually require allowed scoped and permissions for specific resources - for a specific user.

All this is documented on Keycloak Authorization

It's a bit vague I agree, so hopefully, you'll perhaps find some more useful info here Obtain RPT without having to invoke Keycloak API twice

Please note again

  • you aren't supposed to require permissions for all available resources, for a user, but to request one by one and possibly extend your RPT. E.g. You would send a request per each required resource.

If for any technical reason, you cannot do it like this and you still want to require all permissions at once - the best yo can achieve, as already said, is getting the RPT token once a user logs in (obtains a JWT token). But this is still (minimum) two requests to Keycloak

In theory you could extend Keycloak in such a way, it returns permissions in the JWT right away, but this wasn't done by anyone so far as it would require a lot of work and keycloak tweaking, and would still be in question whether it's possible to do so.

eja
  • 4,677
  • 3
  • 21
  • 30