Keycloak 使用不同的客户端重新验证经过身份验证的用户

Posted

技术标签:

【中文标题】Keycloak 使用不同的客户端重新验证经过身份验证的用户【英文标题】:Keycloak reauthenticate an Authenticated user with a different client 【发布时间】:2021-01-04 23:37:21 【问题描述】:

如果我有一个用户在领域 R 下使用公共客户端 C1 使用 keycloak 进行身份验证,我是否可以在 keycloak 中点击一个端点,该端点将为同一领域 R 下的不同公共客户端 C2 生成新的访问令牌?

[更新 #1] 我尝试使用刷新令牌为 C2 客户端获取新的访问令牌,但出现以下错误:

Invalid refresh token. Token client and authorized client don't match

[更新 #2] 所以,上面给了我尝试使用交换令牌授权类型的想法,我现在可以使用它了。

curl --request POST \
  'https://myhost.com.au/auth/realms/<my realm>/protocol/openid-connect/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange' \
  --data-urlencode 'subject_token=<c1 access token>' \
  --data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:access_token' \
  --data-urlencode 'requested_token_type=urn:ietf:params:oauth:token-type:refresh_token' \
  --data-urlencode 'client_id=<c2 client id>'

【问题讨论】:

如果它们在同一领域下,为什么要生成新的访问令牌? @ravthiru 将新客户端的范围/声明获取到访问令牌中。 @ravthiru 他的问题完全有道理:请参阅keycloak.org/docs/latest/server_admin/#_role_scope_mappings 领域角色不一定暴露在所有客户端的访问令牌中。 【参考方案1】:

你的问题很有道理。不幸的是,角色范围映射文档对于如何在切换到不同的客户端时生成新的访问令牌是难以捉摸的。

有一个Oauth2 RFC about token exchange。从Keycloak 11.0.2 token exchange is documented as a technology preview 开始,必须使用-Dkeycloak.profile.feature.token_exchange=enabled 启用

您可以通过这种方式交换代币(实际上取自问题):

Method: POST
URL: https://<keycloak.host>/auth/realms/myrealm/protocol/openid-connect/token
Body type: x-www-form-urlencoded
Form fields:    
. grant_type: urn:ietf:params:oauth:grant-type:token-exchange
. subject_token: <C1-access-token> 
. subject_token_type: urn:ietf:params:oauth:token-type:access_token
. requested_token_type=urn:ietf:params:oauth:token-type:refresh_token
. client_id: <C2-client-id>

这是来自"role scope mapping" documentation 的一些上下文,供其他读者阅读。

当创建 OIDC 访问令牌或 SAML 断言时,所有用户 默认情况下,用户的角色映射作为声明添加到 令牌或断言。 [...] 访问令牌经过数字签名,可以 实际上被应用程序重新使用以远程调用其他 安全的 REST 服务。这意味着如果应用程序获得 受到威胁或在该领域注册了流氓客户端, 攻击者可以获得具有广泛权限的访问令牌 并且您的整个网络都受到了威胁。这是角色范围 映射变得很重要。

角色范围映射是一种限制声明的角色的方法 在访问令牌内。当客户端请求用户 经过身份验证,他们收到的访问令牌将仅包含 您为客户端范围明确指定的角色映射。

[...] 要更改此默认行为,您必须明确关闭 Full Scope Allowed 开关并声明您想要的特定角色 在每个单独的客户中。或者,您也可以使用客户端 范围为一整套定义相同的角色范围映射 客户。

【讨论】:

@ShaneRowatt 好的,感谢您告诉我。我用您的解决方案更新了我的答案,并为未来的读者提供了额外的参考。

以上是关于Keycloak 使用不同的客户端重新验证经过身份验证的用户的主要内容,如果未能解决你的问题,请参考以下文章

无需重定向到 Keycloak 的客户端身份验证

使用 Keycloak 进行微服务身份验证

如何使用 Keycloak 和 PKCE 流实现 React SPA 身份验证?

Keycloak CIBA 身份验证失败并显示“发送身份验证请求失败”

使用spring boot(安全)和keycloak启用角色身份验证?

KeyCloak 在身份验证代码流错误后重定向回身份提供者