Keycloak Authorization: Obtaining Permissions
Question: Can backend client use “Access Token” obtained by “frontend” client and use it to ‘authorization check’ (Keycloak Policies) and pass “claim_token” in it? For me it returns
error: “Public clients are not allowed to send claims”
I understand Keycloak’s concern from error message. It is not allowing any public client to push any arbitrary attributes to keycloak. This makes sense to me. But, why keycloak is treating this request is coming from “public client”? Is it because “azp” in AcccessToken is set to “frontend-client” (client_id)? How can we ensure Keycloak that this request is actually from “backend” and it is OK to allow this.
How can ‘backend client’ do authorization using ‘Access Token’? Providing this ‘Access Token’ is also important as Keycloak Policies will then do other checks like: roles, groups, etc. based on what is inside claims of AccessToken.
Note: Without “claim_token”, this request succeds and I am able to test “postivie” and “negative” test cases for different users in keycloak using keycloak policies. This works so well.
I think I am missing something here.
Code:
keycloak_openid = KeycloakOpenID(server_url=SERVER_URL,
realm_name=REALM_NAME,
client_id=BACKEND_CLIENT_ID,
client_secret_key=CLIENT_SECRET)
token = keycloak_openid.token(username=username,
password=password)
r = Resource(resource=resource)
s = Scope(scope=scope)
permission = r(s)
print(f"Resource and Scope: {permission}")
permissions = [permission]
auth_url = "https://localhost:8443/realms/test-realm/protocol/openid-connect/token"
claim_token_data = {
"organization_id": ["123456", "895743"],
"user_organization_id": ["98761", "93658"],
}
claim_token = get_additional_claim_token(claim_token_data)
payload = {
"grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
"permission": ",".join(str(permission) for permission in permissions),
"response_mode": "decision",
"audience": BACKEND_CLIENT_ID,
"claim_token_format": "urn:ietf:params:oauth:token-type:jwt",
"claim_token": claim_token,
}
headers = {
"Authorization": "Bearer " + token['access_token'],
"Content-Type": "application/x-www-form-urlencoded",
}
response = _send_request("post",
url=auth_url,
data=payload,
headers=headers)