role 与 group 的映射,以及确认令牌里生效
目标
创建 realm role、client role、group 和 composite role,亲自确认它们如何进入令牌,并掌握通过 scope 缩小令牌内容的方法。
为什么重要
“已经授予 role,为什么令牌里看不到?”是使用 Keycloak 的团队一定会遇到一次的问题。原因通常是以下三种之一:不知道 realm role 与 client role 会进入令牌中的不同路径(realm_access.roles 与 resource_access.<클라이언트>.roles);client 的 full scope allowed 被关闭;或者期待从 group 继承,却没有配置 mapping。本实验会分别创建这三种情况并亲眼确认。特别是第 7 步的 scope 限制,既是减少令牌大小、遵守最小权限原则的实际技巧,也是此问题的常见原因。
步骤
- 在 realm
labhub2中创建 realm roleorder-reader和order-admin。执行kcadm.sh get roles -r labhub2时必须能看到两者。 - 在 client
api-svc中创建 client rolerefund。 - 向用户
dev1授予 realm roleorder-reader和 client rolerefund。 - 以
dev1通过 password grant 获取令牌,并将 payload 保存到/root/kr/claims.json。realm_access.roles中必须有order-reader,resource_access.api-svc.roles中必须有refund。 - 创建 group
team-payments,为其映射 realm roleorder-admin,并把dev1加入该 group。新令牌的realm_access.roles中必须出现order-admin。在/root/kr/group.txt中写入group=team-payments inherited=order-admin。 - 将
order-admin设为 composite role,并让它包含order-reader。在/root/kr/composite.txt中写入composite=true includes=order-reader。 - 将 client
web-app的fullScopeAllowed改为 false,确认通过该 client 获取的令牌中不再包含order-admin。在/root/kr/scope.txt中写入full_scope=false order_admin_in_token=false。
参考
- 授予 role:
kcadm.sh add-roles -r labhub2 --uusername dev1 --rolename order-reader - 授予 client role:
kcadm.sh add-roles -r labhub2 --uusername dev1 --cclientid api-svc --rolename refund - 对令牌的第二段进行 Base64URL 解码即可得到 payload。
- 常见错误 1:在
resource_access中寻找 realm role。 - 常见错误 2:只把用户加入 group,却遗漏 role mapping。group 本身不会授予权限。
创建 realm role
在 realm labhub2 中创建 realm role order-reader 和 order-admin。执行 kcadm.sh get roles -r labhub2 时必须能看到两者。
这是在整个 realm 中具有意义的 role。先创建两个,后面即可将它们组合成 composite。
创建 client role
在 client api-svc 中创建 client role refund。
它只在特定 client 内有意义。当存在多个服务时,可以避免名称冲突。
向用户授予 role
向用户 dev1 授予 realm role order-reader 和 client role refund。
realm role 与 client role 在授予命令中指定目标的方式不同。
确认 role 是否进入令牌
以 dev1 通过 password grant 获取令牌,并将 payload 保存到 /root/kr/claims.json。realm_access.roles 中必须有 order-reader,resource_access.api-svc.roles 中必须有 refund。
realm role 与 client role 进入的 JSON 路径不同。
创建 group、映射 role 并加入用户
创建 group team-payments,为其映射 realm role order-admin,并把 dev1 加入该 group。新令牌的 realm_access.roles 中必须出现 order-admin。在 /root/kr/group.txt 中写入 group=team-payments inherited=order-admin。
不要逐个授予 300 名用户,而是把 role 授予 group,再加入用户。role 会被继承。
配置 composite role
将 order-admin 设为 composite role,并让它包含 order-reader。在 /root/kr/composite.txt 中写入 composite=true includes=order-reader。
一个 role 可以包含另一个 role。只授予上层 role 时,下层 role 也应同时进入令牌。
通过 scope 从令牌中排除 role
将 client web-app 的 fullScopeAllowed 改为 false,确认通过该 client 获取的令牌中不再包含 order-admin。在 /root/kr/scope.txt 中写入 full_scope=false order_admin_in_token=false。
关闭 client 的 full scope allowed 后,没有 mapping 的 role 会从令牌中消失。