10

在微服务架构中,我们使用来自 keycloak 的 JWT 令牌。现在我们想要获得第二个权限更少的访问令牌(更少的声明/更少的角色)。用例是:新的访问令牌应该允许其所有者访问文档存储中的一个文档。为什么?限制某人在窃取此令牌时可能造成的损害。

理想情况下,我们可以通过特殊的 refresh_token 调用获得第二个令牌(持有刷新令牌的用户有权获得完全访问令牌,因此他也应该能够获得部分访问令牌)。我们怎么能这样做?

使用范围似乎不起作用:给定范围列表仅在登录时评估(因此在刷新令牌时,我不能采用范围列表)。

我还尝试了解https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_overview或 RPT。但不幸的是,我缺少一些文档(我的尝试失败了)。

还有其他想法吗?或者甚至是一个展示如何做到这一点的例子?

稍后编辑以使我关于 RPT 的问题更加明确: https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_overview说:

... Keycloak 授权服务提供对 OAuth2 的扩展,以允许根据与所请求的资源或范围相关的所有策略的处理来发布访问令牌。这意味着资源服务器可以根据服务器授予并由访问令牌持有的权限来强制访问其受保护的资源。在 Keycloak 授权服务中,具有权限的访问令牌称为请求方令牌或简称 RPT。

这种具有权限的访问令牌可以用于我们的目标吗?

在我的实验中,我可以通过 grant_type=urn:ietf:params:oauth:grant-type:uma-ticket 获得令牌。但是有一些问题:

  • 我不得不更改 keycloak 中的一些设置以启用权限(在它会说“客户端不支持权限”之前)。进行这些更改后,我的正常登录调用将不再起作用(我可以在我的令牌仍然有效时进行测试)。我不得不修改我的 keycloak 配置才能继续工作。

  • 我不太了解用于此功能的权限模型

一个端到端的例子会很有用(Keycloak 文档中的例子有点抽象)。

4

1 回答 1

1

我已经进入了文档,并且可以通过保护您的资源服务器(您的应用程序)以充当受 UMA 保护的资源服务器来实现您想要的。在这里,您有一个基本示例,说明了可以通过以下方式实现的目标:

Keycloak 是一个符合 UMA 2.0 的授权服务器,可提供大多数 UMA 功能。

例如,考虑用户 Alice(资源所有者)使用网上银行服务(资源服务器)来管理他的银行账户(资源)。有一天,爱丽丝决定向会计专业人士鲍勃(请求方)开设她的银行账户。但是,Bob 应该只能查看(范围)Alice 的帐户。

作为资源服务器,网上银行服务必须能够保护 Alice 的银行账户。为此,它依靠 Keycloak Resource Registration Endpoint 在服务器中创建代表 Alice 银行账户的资源。

此时,如果 Bob 试图访问 Alice 的银行账户,访问将被拒绝。网上银行服务为银行账户定义了一些默认策略。其中之一是只有所有者(在本例中为 Alice)才被允许访问她的银行账户。

然而,关于 Alice 隐私的网上银行服务也允许她更改银行账户的特定政策。她可以更改的其中一项政策是定义允许哪些人查看她的银行帐户。为此,网上银行服务依靠​​ Keycloak 向 Alice 提供一个空间,她可以在其中选择个人以及允许他们访问的操作(或数据)。在任何时候,Alice 都可以撤销访问或授予 Bob 额外的权限。

然后使用策略执行器来触发此保护:

如果资源服务器受到策略执行器的保护,它会根据承载令牌的权限响应客户端请求。通常,当您尝试使用无权访问受保护资源的不记名令牌访问资源服务器时,资源服务器会以 401 状态代码和 WWW-Authenticate 标头进行响应。

HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
    as_uri="https://${host}:${post}/auth/realms/${realm}",
    ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"

这里有两个部分你需要做。第一个是为您要保护的应用程序路径添加策略实施。然后,酱汁来了,您需要配置 UMA 部分。UMA 的好处在于它在授权过程中添加了一个额外的票证系统,并且该票证是按资源分配的(实际上,它们是在您尝试访问受保护的资源时分配的)。

客户端请求受保护的资源而不发送 RPT

curl -X GET \
  http://${host}:8080/my-resource-server/resource/1bfdfe78-a4e1-4c2d-b142-fc92b75b986f

资源服务器使用权限票证和 as_uri 参数将响应发送回客户端,其中包含 Keycloak 服务器的位置,以获取 RPT 票证应发送到的位置。资源服务器以许可票响应

HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="${realm}",
    as_uri="https://${host}:${post}/auth/realms/${realm}",
    ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"

因此,客户端请求资源,并获得一张带有 Keycloak 服务器位置的票证,以便将该票证交换为 RPT。这是客户端发布令牌端点,以便获取 RPT:

curl -X POST \
  http://${host}:${port}/auth/realms/${realm}/protocol/openid-connect/token \
  -H "Authorization: Bearer ${access_token}" \
  --data "grant_type=urn:ietf:params:oauth:grant-type:uma-ticket" \
  --data "ticket=${permission_ticket} \
  --data "submit_request=true"

这将为您提供仅对访问您第一次询问的资源有效的 RPT。说这个:

{
  "authorization": {
      "permissions": [
        {
          "resource_set_id": "d2fe9843-6462-4bfc-baba-b5787bb6e0e7",
          "resource_set_name": "Hello World Resource"
        }
      ]
  },
  "jti": "d6109a09-78fd-4998-bf89-95730dfd0892-1464906679405",
  "exp": 1464906971,
  "nbf": 0,
  "iat": 1464906671,
  "sub": "f1888f4d-5172-4359-be0c-af338505d86c",
  "typ": "kc_ett",
  "azp": "hello-world-authz-service"
}

您还需要管理用户对其资源的访问。此处使用管理 UI 完成,但您可能需要从应用程序正确配置它,调用 Keycloak API。

于 2019-02-16T19:44:22.680 回答