当访问令牌中没有身份时,如何使用 JWT 限制用户使用他们的资源?
Posted
技术标签:
【中文标题】当访问令牌中没有身份时,如何使用 JWT 限制用户使用他们的资源?【英文标题】:How to restrict a user to THEIR resources using JWT when there is no identity in the Access Token? 【发布时间】:2019-12-24 21:46:13 【问题描述】:我们有一个这样的 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",
....
如果我们在 Authorization: Bearer <ID Token>
中使用此 ID 令牌,我们可以编写代码(自定义授权者或应用内代码)以确保 /customer/customerId/bill
中的 customerId
等于提供的令牌中 custom:customerId
的值,我们已经保护了我们的 API。
但后来我们读到了that you should not use ID tokens to secure APIs。重点是:
“(ID)令牌的受众(aud 声明)设置为应用程序的标识符,这意味着只有这个特定的应用程序才能使用此令牌。”
看来我们需要发送一个访问令牌来保护 API。使用 Cognito,我们无法将用户身份的任何概念添加到访问令牌中。例如,我们不能添加像 user:4044
这样的自定义范围。
人们在这里建议的一种方法是使用提供的访问令牌在服务器端调用 Cognito 的 /userinfo
端点,以了解用户是谁。这将使我们能够编写调用此端点并声明权限的代码(自定义授权程序或应用内代码)。但它是每个请求的端点调用,这似乎很疯狂。
我们想到的一个想法是使用访问令牌来保护对 API 本身的访问,但也需要 ID 令牌作为查询参数或标头,以允许我们进行细粒度的访问控制。但这也开始让人觉得不对劲。
确定这是一个已解决的问题吗?在这里做什么是正确的?
【问题讨论】:
既然您将 JWT 令牌发送给身份验证器进行身份验证,为什么不在您的 lambda 函数中解析 JWT 令牌,如果 customerId = 他们尝试访问的路径,请允许它。customerId
不在令牌@BrianMcCall 中
【参考方案1】:
对不起,这个问题已经有一年了,所以我的回答可能无关紧要。但是对于未来的流浪者,我会说,鉴于 cognito 在允许访问令牌中的自定义声明方面的局限性,调用 /userinfo 路由绝对是最好的方法。
API GATEWAY 允许您缓存给定用户的授权方响应,因此您不会在每个请求上都调用端点。请注意,某些实现建议将其作为确保令牌未被撤销的一种方式。
【讨论】:
以上是关于当访问令牌中没有身份时,如何使用 JWT 限制用户使用他们的资源?的主要内容,如果未能解决你的问题,请参考以下文章
如何以管理员用户身份撤销用户的访问令牌和刷新令牌?在 Oauth2 中使用 JWT