Keycloak身份验证:外部用户如何在不暴露客户端机密的情况下获取令牌

max*_*vry 6 openid-connect keycloak

我有一个关于 keycloak 如何在没有 GUI 访问权限的情况下与客户端一起工作的问题。

基本上我有:

  • 配置有领域、客户端(访问类型机密)和用户的 keycloak 服务器
  • 具有 GUI 的服务器应用程序,还提供 API,通过 keycloak 进行安全保护(客户端、用户、blablabla)

这已经可以工作了,因为我可以登录 GUI、进行重定向等。

当我可以访问 GUI 时,即使访问 API 也能正常工作:我登录 UI,按照重定向操作并让 UI 显示令牌。人类(为了区分用户和应用程序)可以在任何 API 客户端中使用令牌。

在这种情况下,用户永远不会看到客户端秘密,这本质上是正确的方式。(请注意,我非常愿意接受人们告诉我我的直觉是错误的!)

到目前为止我无法做的是找到服务器应用程序(没有 GUI)可以获得有效令牌的方式?

据我了解,authorization_endpoint需要客户端id和客户端密钥来获取令牌,我宁愿避免:我不认为将我的客户端密钥提供给我的所有“客户”是正确的方法去做吧。

或者,我可以在我的客户端上创建一个 API,该 API 会请求用户凭据并代表其请求令牌,但这会将客户端凭据暴露给我的应用程序,这违背了整个概念!

我尝试将客户端访问类型设置为公共,但是当我使用下面的 API 调用时,我也收到错误:

POST /auth/realms/realmname/protocol/openid-connect/tokenAPI 
Run Code Online (Sandbox Code Playgroud)
'grant_type=client_credentials'
'client_id=client_id'
'username=username'
'password=password'
Run Code Online (Sandbox Code Playgroud)
{
    "error": "unauthorized_client",
    "error_description": "Public client not allowed to retrieve service account"
}
Run Code Online (Sandbox Code Playgroud)

有人知道这应该如何完成吗?

提前致谢。

最大限度

bsa*_*ino 4

(...) 服务器应用程序(没有 GUI)可以获取有效令牌...通常使用Client Credentials流程。

但在这种情况下,我们会为您的服务器(客户端?)应用程序定义一个专用客户端来进行身份验证。返回的令牌(未绑定到特定用户)将用于对允许的应用程序(即您的经典 GUI 或 API 客户端)进行授权。

所以,基本上你应该(简而言之):

  • 在您的 Keycloak 中定义特定的机密 Client
  • 将所需的应用程序(或其他客户端)添加到 Client Scope(s)。您想要从该客户端传递授权的人。
  • 使用流程对此客户端进行身份验证Client Credentials(给定令牌端点、客户端 ID、凭据、范围)
  • 确保您通过身份验证TLS并且参数包含在request body(而不是标头中 - 以增强隐私)
  • 进一步加强客户的安全性

当您不再希望此特定服务器(客户端?)应用程序访问您的应用程序时,您可以更改相应的“身份验证”客户端的秘密/凭据或直接将其删除。


“我不认为将我的客户秘密告诉我的所有‘客户’是正确的做法。”

你是对的,上面提出的方法严格避免了这种情况。每个客户都有自己的凭据。

编辑

(添加更多细节)

通过执行上述操作,您最终会得到以下方案:

                                   Flow         Keycloak Server
C/S app. or Customer X  <--- Client Creds --->  Auth. Client X
                         --- Access Token --->  Appl. Client    <-->  Appl. Server

C/S app. or Customer Y  <--- Client Creds --->  Auth. Client Y
                         --- Access Token --->  Appl. Client    <-->  Appl. Server

         Browser users  <--- Standard  ------>  Appl. Client    <-->  Appl. Server
Run Code Online (Sandbox Code Playgroud)

注意:这不是详细的流程图。箭头在这里主要显示关系。

最后,请注意,这里的术语可能略有不同,但所提出的方法与 Google 使用的基本相同。所以你也可以从那里得到一些灵感: