我想创建一个用户并为其分配一个客户端角色在 Keycloak 的单个 API 中我已附上详细信息。
我有这个API
http://testkeycloak.com:8085/auth/admin/realms/engineer/users
{
"enabled":true,
"username":"joshbiden",
"email":"[email protected]",
"firstName":"Josh",
"lastName":"biden",
"attributes":
{
"Mobile Number":"3333332332"
},
"clientRoles":
{
"name": "DEVELOPER"
},
"credentials":
[
{
"type":"password",
"value":"rollback",
"temporary":false
}
]
}
客户角色 - 详细信息
{
"id": "32e432da-d0c0-45f8-a67d-f3146b7a24b4",
"name": "DEVELOPER",
"composite": false,
"clientRole": true,
"containerId": "343434-7631-4187-ac76-ad78de119b90"
}
如何将两个客户端的角色分配给用户,我尝试添加用户但遇到未知错误。让我知道同样的解决方案
我想创建一个用户并为其分配一个客户端角色 Keycloak 中的 API 我已附上详细信息。
不幸的是,不可能通过单个 API 调用来做到这一点,即使 Keycloak Admin Rest API 文档另有推断。这可以通过查看此 GitHub 问题 来确认。引用该帖子的回复(来自 Keycloak 项目负责人Stian Thorgersen):
因此,不幸的是,@Devendra Mahajan的答案根本不正确。
解决方案是执行两次调用,即:
首先使用端点
POST /{realm}/users
并使用以下数据创建用户(无角色):
{
"username": "joshbiden",
"enabled": true,
"firstName": "Josh",
"lastName": "biden",
"email": "[email protected]",
"attributes": {
"Mobile Number": [
"3333332332"
]
},
"credentials": [{
"type":"password",
"value":"rollback",
"temporary":false
}]
}
其次,使用端点分配角色:
POST /{realm}/users/{id}/role-mappings/clients/{id of client}
数据:
[{
"id": "32e432da-d0c0-45f8-a67d-f3146b7a24b4",
"name": "DEVELOPER",
"composite": false,
"clientRole": true,
"containerId": "343434-7631-4187-ac76-ad78de119b90"
}]
一步一步
警告: 从
Keycloak 17 Quarkus 发行版开始,
/auth
路径已被删除。因此,您可能需要从此答案中显示的端点调用中删除 /auth
。
要使用Keycloak Admin REST API,您需要具有适当权限的用户提供的访问令牌。我将使用来自
admin
领域的 master
用户:
curl "https://${KEYCLOAK_HOST}/auth/realms/master/protocol/openid-connect/token" \
-d "client_id=admin-cli" \
-d "username=$ADMIN_NAME" \
-d "password=$ADMIN_PASSWORD" \
-d "grant_type=password"
您将获得带有管理员令牌的 JSON。从该响应中提取属性
access_token
的值。让我们将其保存在变量$ACCESS_TOKEN
中以供以后参考。
要在您的领域$REALM_NAME
中
创建用户:
curl -X POST "https://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users"
-H "Content-Type: application/json" \
-H "Authorization: bearer $ACCESS_TOKEN" \
-d "${USER_JSON_DATA}"
有需要的人还可以看看我在 GitHub 上自动创建用户的脚本,即 this 或 this。
要将客户端角色分配给用户,您需要事先了解以下字段:
要从您的领域$REALM_NAME
获取用户ID:
curl -X GET "https://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users/?username=${USERNAME}" \
-H "Content-Type: application/json" \
-H "Authorization: bearer $ACCESS_TOKEN"
从响应中提取用户
id
,例如如下
jq -r ".[] | select(.username==\"$USERNAME\")" | jq -r id
并将其保存在变量
${USER_ID}
中。
要获取客户端
id
,请使用参数clientID
调用端点获取客户端:
curl -X GET "${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/clients?clientId=${CLIENT_ID}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"
从响应中提取 id(例如, jq -r .[0].id)并将其保存在变量
${ID_OF_CLIENT}
中。
通过之前的
id
,您可以获得客户端角色,如下所示:
curl -X GET "http://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/clients/${ID_OF_CLIENT}/roles/${ROLE_NAME}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}"
将json响应保存在
${CLIENT_ROLE}
中,并将角色分配给用户,如下所示:
curl -X POST "http://${KEYCLOAK_HOST}/auth/admin/realms/${REALM_NAME}/users/${USER_ID}/role-mappings/clients/${ID_OF_CLIENT}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-d "${CLIENT_ROLE}"
我已经为上述步骤创建了脚本,可以在此处访问并使用脚本getClientRoleByName.sh执行。
试试这个,
{
"enabled": true,
"username": "joshbiden",
"email": "[email protected]",
"firstName": "Josh",
"lastName": "biden",
"attributes": {
"Mobile Number": "3333332332"
},
"clientRoles": {
"<name-of-the-client-in-realm>": ["DEVELOPER"]
},
"credentials": [
{
"type": "password",
"value": "rollback",
"temporary": false
}
]
}
这可以使用部分导入 API 来实现
POST /{realm}/partialImport
使用此 API,您还可以在一次调用中导入多个用户。 但这不是更新的解决方案。
身体样本:
{
"users": [
{
"username": "user1",
"enabled": true,
"totp": false,
"emailVerified": true,
"firstName": "First name",
"lastName": "Last name",
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
},
"groups": [
],
"realmRoles": [
]
},
{
"username": "user2",
"enabled": true,
"totp": false,
"emailVerified": true,
"firstName": "User 2",
"lastName": "Last name",
"disableableCredentialTypes": [],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
},
"groups": [
],
"realmRoles": [
"some realm role"
],
"clientRoles": {
"some client": [
"some client role"
]
}
}
]
}
这基本上是 dreamcrash 的答案之上的额外信息,对于评论来说太长了。
要添加多个角色,请提供一个数组,如下所示:
curl \
"http://$host/admin/realms/$realm/users/$user_uuid/role-mappings/clients/$client_uuid" \
-H "Authorization: bearer $token" \
-H "Content-Type: application/json" \
-d "[{\"id\":\"uuid-for-RoleA\",\"name\":\"RoleA\"},{\"id\":\"uuid-for-RoleB\",\"name\":\"RoleB\"},{etc}]"
这是针对
bash
的,因此我根据 JSON 引号的要求添加了额外的反斜杠。
角色必须作为RoleRepresentation对象的数组提供。唯一的两个必填字段是
id
和 name
(奇怪的是,您需要 id
和 name
;在 Keycloak 23.0.1 上进行了测试)。您也可以提供整个 RoleRepresentation
,如上面的答案所示。因此,简而言之,在开始之前您需要找到大量 UUID:用户、客户端以及您想要的每个角色。
另请注意,这不设置客户端角色:它只是添加客户端角色。您还必须使用
DELETE
而不是 POST
删除任何不需要的客户端角色。所以,整个事情有点混乱。
kcadm.sh
替代方案要简单得多,因为您不需要查找任何UUID,但您仍然需要删除您不想要的角色。