首页 > 解决方案 > 当访问令牌中没有身份时,如何使用 JWT 限制用户使用他们的资源?

问题描述

我们有一个这样的 REST 资源:

/customer/{customerId}/bill

我们希望使用从 AWS Cognito 返回的 JWT 令牌来保护对该资源的访问。

这里{customerId}不是 Cognito 用户 ID,而是特定于域的 ID。我们已将此域特定 ID 作为自定义属性添加到 Cognito 用户。它来自 Cognito 返回的 ID 令牌,如下所示:

{
  "sub": "xxxxxxxx-852f-474d-aa9e-a50fd832bcb8",
  "aud": "xxxxxxxxsijed6uf54dh0uhi",
  "custom:customerId": "4044",
  "event_id": "xxxxxx-fc0c-4ffc-affa-f8987714fb2b",
  "token_use": "id",
  ....
}

如果我们在 in 中使用此 ID 令牌,Authorization: Bearer <ID Token>我们可以编写代码(自定义授权者或应用内代码)以确保customerIdin/customer/{customerId}/bill等于custom:customerId提供的令牌中的值,并且我们已经保护了我们的 API。

但后来我们读到您不应该使用 ID 令牌来保护 API。关键是:

(ID) 令牌的受众(aud 声明)设置为应用程序的标识符,这意味着只有这个特定的应用程序才能使用此令牌。

所以看来我们需要发送一个访问令牌来保护 API。使用 Cognito,我们无法将用户身份的任何概念添加到访问令牌中。例如,我们不能添加自定义范围user:4044

人们在这里建议的一种方法是/userinfo使用提供的访问令牌在服务器端调用 Cognito 的端点,以了解用户是谁。这将使我们能够编写调用此端点并声明权限的代码(自定义授权程序或应用程序内代码)。但它是每个请求的端点调用,这似乎很疯狂。

我们想到的一个想法是使用访问令牌来保护对 API 本身的访问,但也需要 ID 令牌作为查询参数或标头,以允许我们进行细粒度的访问控制。但这也开始让人觉得不对劲。

确定这是一个已解决的问题吗?在这里做什么是正确的?

标签: jwtamazon-cognito

解决方案


抱歉,这个问题已经有一年了,所以我的回答可能无关紧要。但是对于未来的流浪者,我会说,鉴于 cognito 在允许访问令牌中的自定义声明方面的局限性,调用 /userinfo 路由绝对是最好的方法。

API GATEWAY 允许您缓存给定用户的授权方响应,因此您不会在每个请求上都调用端点。请注意,某些实现建议将其作为确保令牌未被撤销的一种方式。


推荐阅读