Warm tip: This article is reproduced from serverfault.com, please click

Keycloak: Access token client-1 to manage client-2 resources

发布于 2020-11-27 13:36:19

I have two clients in Keycloak:

  1. CP: Client public
  2. CC: Client confidential with Service Accounts enabled and several resources.

Resources owners are users who created them and they manage the access too.

The User (U) who created the Resource (R) can log in to CC and use the access token for call endpoints on CP.

Now I would like U will be able to set UMA policies, but the access token is from CP, not from CC where the resources are, so Keycloak is complaining about de token.

org.keycloak.authorization.client.util.HttpResponseException: Unexpected response from server: 403 / Forbidden / Response from server: {\"error\":\"invalid_clientId\",\"error_description\":\"Client application [CP] is not registered as a resource server.\"}
fun onlyOwner(accessToken: String, id: String, resourceId: String) {
   val request = UmaPermissionRepresentation()
   request.name = "Only owner can view $id"
   request.description = "Only owner can view this resource"
   request.scopes = setOf(ResourceScope.VIEW)
   request.condition = ONLY_OWNER_CONDITION
   authzClient.protection(accessToken).policy(resourceId).create(request)
}

Keycloak docs mention the following: " The Policy API is available at: http://${host}:${port}/auth/realms/${realm_name}/authz/protection/uma-policy/{resource_id} This API is protected by a bearer token that must represent a consent granted by the user to the resource server to manage permissions on his behalf. The bearer token can be a regular access token obtained from the token endpoint using:

  • Resource Owner Password Credentials Grant Type
  • Token Exchange, in order to exchange an access token granted to some client (public client) for a token where audience is the resource server

I exchanged the CP client to CC client:

Original token:

{
  "exp": 1606687405,
  "iat": 1606651407,
  "auth_time": 1606651405,
  "jti": "1e4075a9-ce49-4462-91f7-33b8963f56dd",
  "iss": "http://localhost/auth/realms/test",
  "aud": "account",
  "sub": "8381b629-5f10-401c-ae90-bb37769e5f70",
  "typ": "Bearer",
  "azp": "CP",
  "session_state": "6c2d73e7-a4bd-44da-b242-cdf26ec812bc",
  "acr": "1",
  "allowed-origins": [
    "*"
  ],
  "realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization"
    ]
  },
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "openid email profile",
  "email_verified": true,
  "name": "Test First",
  "preferred_username": "test",
  "given_name": "Test",
  "family_name": "First",
  "email": "test@invent.com"
}

Exchanged token:

{
  "exp": 1606687405,
  "iat": 1606652039,
  "auth_time": 1606651405,
  "jti": "0c84f42a-973e-4bc7-9a6d-2c4fec548512",
  "iss": "http://localhost/auth/realms/test",
  "aud": [
    "account",
    "CC"
  ],
  "sub": "8381b629-5f10-401c-ae90-bb37769e5f70",
  "typ": "Bearer",
  "azp": "CP",
  "session_state": "6c2d73e7-a4bd-44da-b242-cdf26ec812bc",
  "acr": "1",
  "allowed-origins": [
    "http://localhost"
  ],
  "realm_access": {
    "roles": [
      "offline_access",
      "uma_authorization"
    ]
  },
  "resource_access": {
    "account": {
      "roles": [
        "manage-account",
        "manage-account-links",
        "view-profile"
      ]
    }
  },
  "scope": "email profile",
  "email_verified": true,
  "name": "Test First",
  "preferred_username": "test",
  "given_name": "Test",
  "family_name": "First",
  "email": "test@invent.com"
}

But the error persists alghout aud changed from account to [account,cc].

Questioner
Fran b
Viewed
0
Fran b 2020-11-30 04:26:53

The solution is exchanging the token using as client_id and client_secret the target client (cc). After that, you can use the access_token returned by Keycloak as bearer token for creating the UMA_Policy.

Exchange public client token to the confidential client token Exchange token

Create a policy with the new access token UMA Policy