如何在Keycloak中安全获取指定客户端的用户角色?
如何安全获取Keycloak中自有客户端的用户角色?
我的应用需要知晓用户所属的本客户端角色,应用已拥有clientId/clientSecret密钥对,也可以启用服务账号。我找到一个Admin API端点:GET /{realm}/clients/{id}/roles/{role-name}/users,但使用该端点需要给服务账号分配realm-management/view-clients角色——这个角色权限过大,会允许查看其他客户端的密钥,可能给其他客户端带来风险,因此不想赋予这个角色。
我目前用以下脚本测试REST API:
KEYCLOAK_HOST=http://localhost:8080 KEYCLOAK_REALM=testrealm KEYCLOAK_CLIENT_ID=testclient KEYCLOAK_CLIENT_SECRET=0TNKx16HJ8ITwnh4wzJluzbAWPDn826m KEYCLOAK_ROLE=testrole1 ACCESS_TOKEN=$(curl -X POST "${KEYCLOAK_HOST}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \ -d "client_id=${KEYCLOAK_CLIENT_ID}" \ -d "client_secret=${KEYCLOAK_CLIENT_SECRET}" \ -d 'grant_type=client_credentials' \ | jq -r '.access_token') # 获取客户端ID KEYCLOAK_CLIENT_UID=$(curl -X GET "${KEYCLOAK_HOST}/admin/realms/${KEYCLOAK_REALM}/clients?clientId=${KEYCLOAK_CLIENT_ID}" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ | jq -r '.[0].id') # 获取指定角色下的用户列表 curl -X GET "${KEYCLOAK_HOST}/admin/realms/${KEYCLOAK_REALM}/clients/${KEYCLOAK_CLIENT_UID}/roles/${KEYCLOAK_ROLE}/users" \ -H "Accept: application/json" \ -H "Authorization: Bearer $ACCESS_TOKEN" | jq .
解决方案
1. 单个用户角色验证:用OpenID Connect(最安全,无需Admin API)
如果只是要验证单个用户的本客户端角色,完全不需要调用Admin API:
- 用户登录后,应用获取的ID令牌(ID Token)中会包含
resource_access.{你的clientId}.roles字段,直接解析该字段就能得到用户在当前客户端的角色列表。 - 也可以调用用户信息端点:
响应中同样会返回curl -X GET "${KEYCLOAK_HOST}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/userinfo" \ -H "Authorization: Bearer {用户的访问令牌}"resource_access字段,包含用户的客户端角色。
这种方式仅依赖应用自身的clientId/clientSecret,无额外权限风险。
2. 批量获取角色用户:给服务账号分配最小细粒度权限
如果需要批量获取某角色下的所有用户,可通过Keycloak的权限细分,避免赋予全局view-clients角色:
- 进入Keycloak控制台,切换到目标领域
testrealm。 - 找到你的客户端
testclient,进入「权限」标签页,开启「授权」开关。 - 进入「服务账号角色」标签页:
- 点击「客户端角色」下拉框,选择
realm-management。 - 不要勾选
view-clients,而是找到并勾选仅针对当前客户端的权限:clients.view和clients.view-roles。
- 点击「客户端角色」下拉框,选择
- 进一步限制权限范围:在「权限」→ 「资源」中,创建仅匹配当前客户端的资源规则,确保服务账号只能访问自身客户端的角色数据。
调整后的脚本无需修改,但此时服务账号仅能访问自己客户端的角色和用户映射,无法查看其他客户端的敏感信息。
内容的提问来源于stack exchange,提问作者Smith John
相关产品推荐
相关产品推荐

