Keycloak - 将客户端范围分配给具有特定角色的用户

问题描述 投票:0回答:2

给出以下设置:

  • 具有领域角色“foo-admin”的用户
  • 名为“foo”的客户端(已启用直接访问授予,公共)
  • 客户端范围“some:scope”(客户端“foo”的可选客户端范围)

当使用客户端“foo”请求访问令牌时,用户应根据其领域角色“foo-admin”获取范围“some:scope”。没有该角色的用户不应该能够获得该范围(即使在请求时)。

我按照这篇博客文章并在客户端范围的范围选项卡下分配了“foo-admin”管理员角色。据我所知,这个设置完全符合我们的要求,但说实话,我发现范围选项卡中的工具提示令人困惑,因为我们首先没有创建用户角色映射或其他内容。工具提示:“范围映射允许您限制客户端请求的访问令牌中包含哪些用户角色映射。”

这个设置可以吗?当工具提示显示有关限制映射的内容时,如何以及为何在范围选项卡中分配角色?

提前致谢

oauth keycloak
2个回答
1
投票

用户的访问令牌仅包括领域角色,而不包括其范围。

如果你想要用户的映射范围,必须调用额外的REST API调用。

概述

设置

  1. 运行Keycloak v18.0.2

  2. 创建

    development
    领域

  3. 创建

    foo
    客户端

  4. 创建

    foo-admin
    角色

  5. 创建

    some:scope
    客户端范围

  6. foo-admin
    分配给
    some:scope

  7. some:scope
    可选客户端范围分配到
    foo
    客户端

  8. 创建

    user
    用户

  9. foo-admin
    角色分配给
    user

现在准备演示。

curl命令演示 它将显示,用户的访问令牌包括分配的领域角色。

获取主令牌 - 凭据是 admin/admin 和一小时 - 用于测试

演示

  1. 获取主人和用户
    access -token
MASTER_TOKEN=$(curl --location --request POST "http://localhost:8080/auth/realms/master/protocol/openid-connect/token" \
-s \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=admin-cli' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=admin' \
--data-urlencode 'password=admin' | jq -r '.access_token')
echo $MASTER_TOKEN


ACCESS_TOKEN=$(curl --location --request POST "http://localhost:8080/auth/realms/development/protocol/openid-connect/token" \
-s \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=foo' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=user' \
--data-urlencode 'password=1234' | jq -r '.access_token')
echo $ACCESS_TOKEN

结果

  1. 显示用户
    access -token
    的角色
jwtd() {
    if [[ -x $(command -v jq) ]]; then
         jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< "${1}"
         echo "Signature: $(echo "${1}" | awk -F'.' '{print $3}')"
    fi
}

jwtd $ACCESS_TOKEN

结果

您可以通过JWT.io网站验证用户令牌。

  1. 获取用户角色的范围

3.1 获取用户角色(*概览红圈3) -

foo-admin

找到

user
user id
-
jq
很有用
-r
选项删除“双引号” '.[0]
is get first item of array. 
.id` 仅获取 id 字段。

USER_ID=$(curl -s --location 'http://localhost:8080/auth/admin/realms/development/users/?username=user' \
--header 'Authorization: Bearer '"$MASTER_TOKEN" | jq -r '.[0]'.id)
echo $USER_ID

curl -s --location 'http://localhost:8080/auth/admin/realms/development/users/'"$USER_ID"'/role-mappings' \
--header 'Authorization: Bearer '"$MASTER_TOKEN" | jq

3.2 获取客户端

foo
的范围
some:scope
(*概览红圈1)

获取客户ID

CLIENT_ID=$(curl -s --location 'http://localhost:8080/auth/admin/realms/development/clients/?clientId=foo' \
--header 'Authorization: Bearer '"$MASTER_TOKEN" | jq -r '.[0]'.id)
echo $CLIENT_ID

获取客户端

foo
的可选范围列表

curl -s --location 'http://localhost:8080/auth/admin/realms/development/clients/'"$CLIENT_ID"'/optional-client-scopes' \
--header 'Authorization: Bearer '"$MASTER_TOKEN" | jq

3.3 获取范围

some:scope
的指定角色(*概览红圈 2) -
foo-admin

获取

some:scope
范围的 id 按
jq
匹配范围列表数组中的
some:scope
名称进行过滤。

SCOPE_ID=$(curl -s --location 'http://localhost:8080/auth/admin/realms/development/client-scopes' \
--header 'Authorization: Bearer '"$MASTER_TOKEN" | jq -r -c '.[] | select(.name | contains("some:scope")).id')
echo $SCOPE_ID

scope id
获取其分配的角色。这将是
foo-admin"
的角色。

curl -s --location 'http://localhost:8080/auth/admin/realms/development/client-scopes/'$SCOPE_ID'/scope-mappings/realm' \
--header 'Authorization: Bearer '"$MASTER_TOKEN"  | jq

最终结论

user
分配了
foo-admin
角色。 它的角色分配了
some:scope
范围。 因此用户可以在
some:scope
范围内进行操作。


0
投票

按照本文的“向用户添加角色并将其映射到范围”部分进行操作https://handbook.digital-blueprint.org/frameworks/relay/howtos/keycloak_scopes/我的keycloak版本是23.0.7按照本文中提到的步骤后,如果用户具有特定角色,我就能够为其分配特定范围。

© www.soinside.com 2019 - 2024. All rights reserved.