Keycloak:访问令牌 client-1 以管理 client-2 资源
Keycloak: Access token client-1 to manage client-2 resources
我在 Keycloak 中有两个客户端:
- CP:客户public
- CC:客户端 机密 启用了 服务帐户 和多个资源。
资源所有者是创建它们的用户,他们也管理访问权限。
创建资源 (R) 的用户 (U) 可以登录到 CC 并将访问令牌用于 CP 上的调用端点。
现在我希望你能够设置 UMA 策略,但是访问令牌来自 CP,而不是来自资源所在的 CC,所以 Keycloak 抱怨 de令牌。
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 文档提到以下内容:
“
政策 API 可在以下网址获得:
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/uma-policy/{resource_id}
此 API 受不记名令牌的保护,该令牌必须代表用户授予资源服务器以代表他管理权限的许可。不记名令牌可以是使用以下方式从令牌端点获取的常规访问令牌:
- 资源所有者密码凭据授权类型
- 令牌交换,以便将授予某些客户端(public 客户端)的访问令牌交换为观众是资源服务器的令牌
我把CP客户端换成了CC客户端:
原始令牌:
{
"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"
}
交换的代币:
{
"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"
}
但错误仍然存在 aud 从 account 更改为 [account,cc] .
解决方案是使用 client_id 和 client_secret 目标客户端 (cc) 交换令牌。之后,您可以使用 Keycloak 返回的 access_token 作为不记名令牌来创建 UMA_Policy.
将 public 客户端令牌交换为机密客户端令牌
使用新的访问令牌创建策略
我在 Keycloak 中有两个客户端:
- CP:客户public
- CC:客户端 机密 启用了 服务帐户 和多个资源。
资源所有者是创建它们的用户,他们也管理访问权限。
创建资源 (R) 的用户 (U) 可以登录到 CC 并将访问令牌用于 CP 上的调用端点。
现在我希望你能够设置 UMA 策略,但是访问令牌来自 CP,而不是来自资源所在的 CC,所以 Keycloak 抱怨 de令牌。
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 文档提到以下内容:
“
政策 API 可在以下网址获得:
http://${host}:${port}/auth/realms/${realm_name}/authz/protection/uma-policy/{resource_id}
此 API 受不记名令牌的保护,该令牌必须代表用户授予资源服务器以代表他管理权限的许可。不记名令牌可以是使用以下方式从令牌端点获取的常规访问令牌:
- 资源所有者密码凭据授权类型
- 令牌交换,以便将授予某些客户端(public 客户端)的访问令牌交换为观众是资源服务器的令牌
我把CP客户端换成了CC客户端:
原始令牌:
{
"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"
}
交换的代币:
{
"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"
}
但错误仍然存在 aud 从 account 更改为 [account,cc] .
解决方案是使用 client_id 和 client_secret 目标客户端 (cc) 交换令牌。之后,您可以使用 Keycloak 返回的 access_token 作为不记名令牌来创建 UMA_Policy.
将 public 客户端令牌交换为机密客户端令牌
使用新的访问令牌创建策略