为啥 Amazon Cognito 不在其访问令牌中返回受众字段?
Posted
技术标签:
【中文标题】为啥 Amazon Cognito 不在其访问令牌中返回受众字段?【英文标题】:Why doesn't Amazon Cognito return an audience field in its access tokens?为什么 Amazon Cognito 不在其访问令牌中返回受众字段? 【发布时间】:2019-04-08 11:27:14 【问题描述】:当 Amazon Cognito 颁发访问令牌时,它不包含 aud
字段。
在documentation for Cognito tokens 中,aud
字段针对 id 令牌(始终设置为与 client_id
相同的值)列出,但不针对访问令牌。
relevant section of the JWT specification 说:
如果处理该声明的主体在此声明存在时未使用“aud”声明中的值标识自己,则必须拒绝 JWT。
那么,这里发生了什么。谁是对的?这是安全问题吗?
我注意到令牌的 iss
部分特定于我的用户池,并且不能被篡改,因为它是由亚马逊签名的,所以我认为我应该是安全的
OAuth 2 和 JWT 非常令人困惑,所以我想获得更多意见。
【问题讨论】:
【参考方案1】:通常,aud
声明用于标识 recipients
或 principal
,以便接收者可以验证 jwt 是否适合其验证。
但是,aud
是可选声明。
因此,AWS 将其保留为可选。
AWS 没有使用 aud 声明来限制谁可以处理 jwt,而是让接收者(例如 aws api gw)检查 client_id
声明以确定是否应该处理 jwt。
参考资料:
https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3
【讨论】:
【参考方案2】:根据我对 RFC 的阅读,我不认为 AWS 做错了什么,特别是(注意我的重点):
如果处理该声明的主体在存在此声明时未将自己标识为“aud”声明中的值,则必须拒绝 JWT。
使用此声明是可选。
我相信这意味着 AWS 很好,因为它只是在访问令牌的情况下省略了声明,但它通过设置它来标识自己(以它自己的方式) client_id
当它确实对 id 令牌提出声明时。
应该注意,访问令牌本身确实对受众进行编码和强制执行;因为当您针对 AWS 的 API 使用它时,它将强制您仅接收为其发布的 client_id/scope 上可用的资源。
【讨论】:
感谢您的回复。我联系了 AWS,与他们讨论了一些事情,包括这个,他们因此向 cognito 开发团队提交了一个功能请求,以考虑选择性地允许在访问令牌中包含“aud”声明,模仿 auth0 和好的。 @Kyanite 你有关于该功能请求的更多信息吗? @Kyanite 关于功能请求的任何消息?缺少audience
声明使得 API Gateway JWT Authorizer 无用,因为它需要一个有效的 audience
值列表。
对于 JWT 授权者,文档说明(现在,如果不是,那么!)授权者的受众条目使用如下:“aud 或 client_id – 必须匹配配置的受众条目之一为授权人。”见docs.aws.amazon.com/apigateway/latest/developerguide/…【参考方案3】:
许多 dotnet Web 应用程序认知教程基于错误的假设,即客户端 ID 将是以下设置中的受众 ID,这将不起作用。
services
.AddAuthentication(options =>
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(options =>
options.Audience = "Client ID";
options.Authority = "https://cognito-idp.ap-southeast-2.amazonaws.com/USERPOOLID";
options.RequireHttpsMetadata = false;
);
暂时的解决方法是不验证观众:
services
.AddAuthentication(options =>
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
)
.AddJwtBearer(options =>
// AWS cognito jwt token does not have aud included so that we cannot validate audience.
// options.Audience = "Client ID";
options.TokenValidationParameters = new TokenValidationParameters
ValidateAudience = false
;
options.Authority = "https://cognito-idp.ap-southeast-2.amazonaws.com/USERPOOLID";
options.RequireHttpsMetadata = false;
);
【讨论】:
【参考方案4】:AWS Cognito 现在似乎在访问令牌上包含 client_id
声明。我没有在任何 AWS 文档中找到它,我唯一能找到的是这个 GitHub 问题:https://github.com/ghdna/cognito-express/issues/11
【讨论】:
是的,包括 client_id 声明,对于 JWT 授权者,文档说明(现在,如果不是,那么!)授权者的受众条目使用如下:“aud 或 client_id – 必须匹配为授权人配置的受众条目之一。”见docs.aws.amazon.com/apigateway/latest/developerguide/…以上是关于为啥 Amazon Cognito 不在其访问令牌中返回受众字段?的主要内容,如果未能解决你的问题,请参考以下文章
使用 amazon cognito 域 UI(从用户池生成)登录后未获得 cognito 访问令牌?
在预认证用户的情况下如何使用 amazon cognito 获取刷新令牌