如何在单个 API 中创建具有多个客户端角色的用户

kri*_*han 1 keycloak keycloak-services keycloak-rest-api

我想创建一个用户并在 Keycloak 的单个API 中为其分配客户端角色,我已附上详细信息。

我有这个API

http://testkeycloak.com:8085/auth/admin/realms/engineer/users

{   
    "enabled":true,
    "username":"joshbiden",
    "email":"email@gmail.com",
    "firstName":"Josh",
    "lastName":"biden",
    "attributes": 
    {
        "Mobile Number":"3333332332"
    },
    "clientRoles": 
    {
        "name": "DEVELOPER"
    },
    "credentials":
    [
    {
        "type":"password",
        "value":"rollback",
        "temporary":false
    }
    ]
}
Run Code Online (Sandbox Code Playgroud)

客户角色 - 详细信息

    {
        "id": "32e432da-d0c0-45f8-a67d-f3146b7a24b4",
        "name": "DEVELOPER",
        "composite": false,
        "clientRole": true,
        "containerId": "343434-7631-4187-ac76-ad78de119b90"
    }
Run Code Online (Sandbox Code Playgroud)

如何将两个客户端的角色分配给用户,我尝试添加用户但面临未知错误。让我知道同样的问题的任何解决方案

dre*_*ash 10

我想创建一个用户并在 Keycloak 的单个 API 中为其分配客户端角色,我已附上详细信息。

不幸的是,不可能通过单个 API 调用来做到这一点,即使Keycloak Admin REST API文档另有推断。可以通过查看此 GitHub 问题来确认这一点。引用该帖子的回复(来自 Keycloak 项目负责人Stian Thorgersen):

因此,不幸的是, @Devendra Mahajan的答案根本不正确。


解决方案是执行两次调用,即:

  1. 一个创建用户
  2. 另一个分配角色

首先使用端点POST /{realm}/users和以下数据创建用户(没有角色):

{
  "username": "joshbiden",
  "enabled": true,
  "firstName": "Josh",
  "lastName": "biden",
  "email": "email@gmail.com",
  "attributes": {
    "Mobile Number": [
      "3333332332"
    ]
  },
  "credentials": [{
    "type":"password",
    "value":"rollback",
    "temporary":false
  }]
}
Run Code Online (Sandbox Code Playgroud)

其次,您使用端点分配角色:

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"
}]
Run Code Online (Sandbox Code Playgroud)

一步步

警告:/authKeycloak 17 Quarkus 发行版开始,该路径已被删除。因此,您可能需要/auth从该答案中显示的端点调用中删除 。

要使用Keycloak Admin REST API,您需要具有适当权限的用户提供的访问令牌。我将使用领域admin中的用户master

{
  "username": "joshbiden",
  "enabled": true,
  "firstName": "Josh",
  "lastName": "biden",
  "email": "email@gmail.com",
  "attributes": {
    "Mobile Number": [
      "3333332332"
    ]
  },
  "credentials": [{
    "type":"password",
    "value":"rollback",
    "temporary":false
  }]
}
Run Code Online (Sandbox Code Playgroud)

您将获得带有管理员令牌的 JSON。access_token从该响应中提取属性值。让我们将其保存在变量中$ACCESS_TOKEN以供以后参考。

要在您的领域中创建用户$REALM_NAME

[{
  "id": "32e432da-d0c0-45f8-a67d-f3146b7a24b4",
  "name": "DEVELOPER",
  "composite": false,
  "clientRole": true,
  "containerId": "343434-7631-4187-ac76-ad78de119b90"
}]
Run Code Online (Sandbox Code Playgroud)

对于那些需要的人,您还可以查看我的脚本,以在 GitHub 上自动创建用户,即thisthis

要将客户端角色分配给用户,您需要事先了解以下字段:

  1. 用户的id
  2. 客户端的id
  3. 客户角色代表

要从您的领域获取用户 ID$REALM_NAME

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"
Run Code Online (Sandbox Code Playgroud)

从响应中提取用户,id例如如下

jq -r ".[] | select(.username==\"$USERNAME\")" | jq -r id
Run Code Online (Sandbox Code Playgroud)

并将其保存在变量中${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}"
Run Code Online (Sandbox Code Playgroud)

从响应中提取 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}"
Run Code Online (Sandbox Code Playgroud)

将 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}"
Run Code Online (Sandbox Code Playgroud)

我已经为上述步骤创建了脚本,可以在此处访问这些脚本并使用脚本getClientRoleByName.sh执行。