给出以下设置:
当使用客户端“foo”请求访问令牌时,用户应根据其领域角色“foo-admin”获取范围“some:scope”。没有该角色的用户不应该能够获得该范围(即使在请求时)。
我按照这篇博客文章并在客户端范围的范围选项卡下分配了“foo-admin”管理员角色。据我所知,这个设置完全符合我们的要求,但说实话,我发现范围选项卡中的工具提示令人困惑,因为我们首先没有创建用户角色映射或其他内容。工具提示:“范围映射允许您限制客户端请求的访问令牌中包含哪些用户角色映射。”
这个设置可以吗?当工具提示显示有关限制映射的内容时,如何以及为何在范围选项卡中分配角色?
提前致谢
用户的访问令牌仅包括领域角色,而不包括其范围。
如果你想要用户的映射范围,必须调用额外的REST API调用。
运行Keycloak v18.0.2
创建
development
领域
创建
foo
客户端
创建
foo-admin
角色
创建
some:scope
客户端范围
将
foo-admin
分配给 some:scope
将
some:scope
可选客户端范围分配到 foo
客户端
创建
user
用户
将
foo-admin
角色分配给 user
现在准备演示。
curl命令演示 它将显示,用户的访问令牌包括分配的领域角色。
获取主令牌 - 凭据是 admin/admin 和一小时 - 用于测试
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
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网站验证用户令牌。
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
范围内进行操作。
按照本文的“向用户添加角色并将其映射到范围”部分进行操作https://handbook.digital-blueprint.org/frameworks/relay/howtos/keycloak_scopes/我的keycloak版本是23.0.7按照本文中提到的步骤后,如果用户具有特定角色,我就能够为其分配特定范围。