令牌刷新时部分JWT令牌

时间:2019-02-07 13:59:31

标签: jwt microservices keycloak rpt

在微服务架构中,我们使用来自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的扩展,以   允许根据所有策略的处理发出访问令牌   与请求的资源或范围相关联。这意味着   资源服务器可以基于以下内容强制访问其受保护资源   服务器授予并由访问令牌持有的权限。在钥匙斗篷   授权服务具有权限的访问令牌称为   简写为请求方令牌或RPT。

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

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

  • 我必须更改密钥斗篷中的某些设置才能启用权限(之前会显示“客户端不支持权限”)。进行这些更改后,我的常规登录呼叫将不再起作用(我可以在令牌仍然有效的同时进行测试)。我必须抓紧自己的keycloak配置才能继续工作。

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

端到端示例将很有用(Keycloak文档中的示例有些抽象)。

1 个答案:

答案 0 :(得分:1)

我已经研究了文档,可以通过保护您的资源服务器(您的应用程序)以充当受UMA保护的资源服务器来实现您想要的目标。 Here you have可以用此实现的基本示例:

  

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

     

作为示例,考虑一个用户Alice(资源所有者)使用   网上银行服务(资源服务器)以管理其银行帐户   (资源)。有一天,爱丽丝决定向鲍勃开设银行帐户。   (请求方),会计专业人员。但是,鲍勃应该   仅有权查看(范围)爱丽丝的帐户。

     

作为资源服务器,Internet Banking Service必须能够   保护爱丽丝的银行帐户。为此,它依赖于Keycloak资源   注册端点在服务器上创建一个资源代表   爱丽丝的银行帐户。

     

此刻,如果Bob尝试访问Alice的银行帐户,请访问   将被拒绝。网上银行服务定义了一些默认值   银行帐户政策。其中之一是,只有所有者   在这种情况下,爱丽丝被允许访问她的银行帐户。

     

但是,有关爱丽丝隐私的网上银行服务   允许她更改银行帐户的特定政策。之一   她可以更改的这些政策是为了确定哪些人是   允许查看她的银行帐户。为此,网上银行服务   依靠Keycloak为Alice提供一个可以选择的空间   个人及其允许访问的操作(或数据)。   爱丽丝可以随时撤消访问权限或授予其他权限   给鲍勃。

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

  

如果资源服务器受策略实施者保护,它将响应   基于承载的许可权的客户端请求   令牌。通常,当您尝试使用以下命令访问资源服务器时:   缺乏访问受保护对象权限的承载令牌   资源,资源服务器以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"

这里您需要完成两个部分。首先是add policy enforcement来提供您想要保护的应用程序的路径。然后,调料到了,您需要configure the UMA part。关于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,该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"
}

您还需要manage users access to their resources。此处是使用管理界面完成的,但是您可能需要通过调用Keycloak API从应用程序中对其进行正确配置。