Skip to content

Extend support for scopes stored in complex JWT tokens like in Keycloak #12324

@MarcialRosales

Description

@MarcialRosales

Is your feature request related to a problem? Please describe.

RabbitMQ supports, in code, a token format called Requesting Party Token used by Keycloak and other vendors like WSO2. Keycloak does not issue this token via the OpenId token endpoint unless you specify the claim type urn:ietf:params:oauth:grant-type:uma-ticket.

This is an example of such RPT format:

{
  "authorization": {
    "permissions": [
      {
        "scopes": [
          "rabbitmq-resource.read:*/*"
        ],
        "rsid": "2c390fe4-02ad-41c7-98a2-cebb8c60ccf1",
        "rsname": "allvhost"
      },
      {
        "scopes": [
          "rabbitmq-resource-read"
        ],
        "rsid": "e7f12e94-4c34-43d8-b2b1-c516af644cee",
        "rsname": "vhost1"
      },
      {
        "rsid": "12ac3d1c-28c2-4521-8e33-0952eff10bd9",
        "rsname": "Default Resource"
      }
    ]
  },
  "scope": "email profile",
}

In addition to the above token format, Keycloak also issues another token format. This time, there are no scopes attribute but roles under the claims realm_access and resource_access:

{
  "jti": "865a14bc-d1d7-4b81-8d14-94c4af2bd61f",
  "exp": 1586670977,
  "nbf": 0,
  "iat": 1586670677,
  "iss": "http://localhost:8090/auth/realms/wstutorial",
  "aud": "account",
  "sub": "e4713c5f-d662-4156-93ee-5110ec6007bd",
  "typ": "Bearer",
  "azp": "demo-app",
  "auth_time": 0,
  "session_state": "3aa0f14a-2178-41b1-bff8-fb6364ac1865",
  "acr": "1",
  "realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization"
    ]
  },
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "profile email",
  "email_verified": false,
  "preferred_username": "johndoe"
}

Describe the solution you'd like

Users of Keycloak who currently depend on the RPT format do not need to do anything, RabbitMQ continue ssupporting that token format. Users who depend on the latter token format can configure RabbitMQ to extract the scopes from those two claims as follows:

auth_oauth2.additional_scopes_key = resource_access.account.roles  real_access.roles

Given that both token formats have in common that scopes are stored deep-nested in maps and lists, there should be only one code that is able to extract scopes from a dot-separated path. And this code should be used for the former token format whose scope's path/key is authorization.permissions.scopes and for the code that uses the configuration variable auth_oauth2.additional_scopes_key to find scopes. This configuration variable can be a single key or multiple keys separated by space(s). Each key can be a single path key like roles, if there is a claim in the token with the name roles. Or it can be a dot-separated key like resource_access.account.roles.

Describe alternatives you've considered

No response

Additional context

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions