#keycloak
#скрытие ключей
Вопрос:
У меня есть два клиента в Keycloak:
- CP: общедоступный клиент
- CC: конфиденциальный клиент с включенными учетными записями служб и несколькими ресурсами.
Владельцы ресурсов — это пользователи, которые их создали, и они также управляют доступом.
Пользователь (U), создавший Ресурс (R), может войти в 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 защищен токеном-носителем, который должен представлять согласие, предоставленное пользователем серверу ресурсов для управления разрешениями от его имени. Токен-носитель может быть обычным токеном доступа, полученным из конечной точки токена с помощью:
- Тип предоставления учетных данных пароля владельца ресурса
- Обмен токеном, чтобы обменять токен доступа, предоставленный некоторому клиенту (общедоступному клиенту), на токен, аудитория которого является сервером ресурсов
Я заменил клиент 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 изменился с учетной записи на [учетная запись, cc].
Ответ №1:
Решение заключается в обмене токена с использованием as client_id и client_secret для целевого клиента (cc). После этого вы можете использовать access_token, возвращаемый Keycloak, в качестве токена на предъявителя для создания UMA_Policy.
Обмен общедоступного токена клиента на конфиденциальный токен клиента