eclipse-ditto / ditto

Eclipse Ditto™: Digital Twin framework of Eclipse IoT - main repository
https://eclipse.dev/ditto/
Eclipse Public License 2.0
667 stars 218 forks source link

Complex JWT placeholder subject mapping - Keycloak RPT integration #1984

Open pedro-nicolau-carvalho opened 1 month ago

pedro-nicolau-carvalho commented 1 month ago

Hello,

I am currently integrating Keycloak with Eclipse Ditto. Since granting user permissions is done elsewhere from ditto, my idea is to map specific resources and scopes as subjects in Ditto and use a user's RPT token as the input of this mapping. The RPT token, granted by keycloak, is a JWT token that contains some user's permissions. The structure is as follows:

{
  "authorization": {
      "permissions": [
        {
          "scopes": [ "device.read" ],
          "resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
          "resource_set_name": "Device 1"
        },
        {
          "scopes": [ "device.read", "device.write" ],
          "resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
          "resource_set_name": "Device 12
        }
      ]
  },
  "jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405",
  "exp": 1464906971,
  "nbf": 0,
  "iat": 1464906671,
  "sub": "f1888f4d-5172-4359-be0c-af338505d86c",
  "typ": "kc_ett",
  "azp": "hello-world-authz-service"
}

my idea is to then, from this RPT, generate subjects:

I have tried using jwt placeholders to convert the JWT token to the format I require, but I am not sure if it is possible. It seems that the supported json operations are very limited. For example, using the token structure above:

Am I correct in assuming that the mapping I want is not currently possible using placeholders?

Thank you.

thjaeckle commented 1 month ago

Hi @pedro-nicolau-carvalho

The JWT placeholder is quite mighty: https://eclipse.dev/ditto/basic-placeholders.html#scope-openid-connect-configuration

It e.g. has a special handling for JSON arrays (and even JSON objects in arrays) - iterating over all entries and "multiplying" the result.

However, it seems we did not consider yet the "array in array" use case. It also seems that only arrays in "root level" are currently supported .. I would say this is a bug, that should work also in nested structures. I will create a ticket for that and can provide a fix.

What you however want to achieve is not yet supported, I fear .. selecting and combining fields only "on the same level". But that is a very valid and useful use case. 👍 We could track that as new issue, I am open for suggestions regarding syntax (probably a function as you suggested would be needed).

pedro-nicolau-carvalho commented 1 month ago

It e.g. has a special handling for JSON arrays (and even JSON objects in arrays) - iterating over all entries and "multiplying" the result.

Is it currently possible to extract a property from a nested JSON object in an array without parsing the JSON object as a string? For example, using the structure from the RPT, is it possible to extract the resource_set_idas the authorization subjects? I have tried using {{ jwt:authorization/permissions/resource_set_id }} and {{ jwt:authorization/permissions/0/resource_set_id }} but without luck

thjaeckle commented 1 month ago

As mentioned: It should be possible .. however it currently only seems to work if the array is directly at the "first level" of the JSON, see created bug issue #1985

For example, using the structure from the RPT, is it possible to extract the resource_set_idas the authorization subjects? I have tried using {{ jwt:authorization/permissions/resource_set_id }} and {{ jwt:authorization/permissions/0/resource_set_id }} but without luck

Yes, that unfortunately is affected by the bug :/

{{ jwt:authorization/permissions/resource_set_id }} should work that way .. Using the array-index is not supported ..