为什么在使用 Cognito 的撤销令牌后,我仍然可以向 API 网关授权请求?



我使用AWS Lambda函数(Node.js 14.x)调用CognitorevokeToken函数来撤销刷新令牌。

根据官方文件"revokeToken"威尔:

撤销指定刷新令牌生成的所有访问令牌。撤销令牌后,不能使用撤销的令牌访问经过Cognito认证的api。

虽然我可以成功撤销刷新令牌&关联的访问令牌,以前创建的访问令牌仍然可以用来访问API网关资源(启用了Cognito用户池身份验证)。

为什么使用Cognito的RevokeToken方法撤销访问令牌后,我仍然可以授权请求到API网关?

刷新标记&然而,使用该刷新令牌创建的访问令牌正在被撤销,API网关将不会拾取此&仍然允许访问

这样做的原因是API网关使用身份令牌来授权API调用,而不是使用访问令牌

文档(我必须承认非常不清楚)提到:

撤销令牌后,不能使用撤销的令牌访问Cognito认证api.

在这种情况下,上面的意思是对于实际上属于 Cognito的API操作吊销令牌,而不是使用Cognito进行身份验证的服务。

这就是为什么你仍然可以通过API网关进行身份验证,因为它将在内部使用未撤销的ID令牌。


为了演示这一点,典型的Cognito身份验证结果如下所示:

{
"AuthenticationResult":{
"AccessToken":"eyJraWQiOiJvZ2JFM2xXN0FWeEpPZjJWRU50MW9RNnRrY3ZOdVRJUUNTZkJpczlBWDFBPSIsImFsZyI6IlJTMjU2In0.eyJvcmlnaW5fanRpIjoiOThjM2QyNTgtYWU1NC00MzBiLWEwNjktYjg4OGZhNWQ5YzkwIiwic3ViIjoiZWE5MGQ2MjktMWI3NS00Y2ZiLThkOWQtZGRmZWJhZGZlZGYzIiwiZXZlbnRfaWQiOiJlODMxZWI1MS1mMjM3LTRhNDctYTM3YS1jNTk5MzBkNzFkZDgiLCJ0b2tlbl91c2UiOiJhY2Nlc3MiLCJzY29wZSI6ImF3cy5jb2duaXRvLnNpZ25pbi51c2VyLmFkbWluIiwiYXV0aF90aW1lIjoxNjM0NDcxOTA1jsda56dsf8sd7f7sdf9sdf6hdf8gfdf8dg89dfg8dfgIiwiZXhwIjoxNjM0NTU4MzA1LCJpYXQiOjE2MzQ0NzE5MDUsImp0aSI6IjNlMWQ1ZmJjLTUwNjMtNGZmNS1iZDIxLWFlZTk1ZjAyZTVjZCIsImNsaWVudF9pZCI6IjNiZHBsZzNxYmwyNWJhczM1aWRuOWU4YWdqIiwidXNlcm5hbWUiOiJxbDAzIn0.FU8fv7bXDFLhUku_A11bLiw2kCdLCIepZ0l4E5t8okC_KgABGE4G_VFZ5E34VYAokuy-npWQaP84PKksnPR-S17phEQ-CWyoL5OM7t5sqkJseikqrgxzMoAgnSn34RUY4FJDhmuM9F5ejNhaKp-uDhDnvYaWe8Qcuz1TfBlgLUwARE1eBMaxqusmPOyJpZOvKcaeiOfqduv_rnN36UjIRaOeeDkht54n0066H9vBYnE1kwkVLlLagCI7kF2agHV6Kkl-cTVZTZjqCYzhOuAba_ZhdedsLn9xrQcY14-qgxfYiBxc-m1CVSZ-ZUTlmRShFrG6aHZDYSlWP38bRgQD8g",
"ExpiresIn":86400,
"TokenType":"Bearer",
"RefreshToken":"eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.ODcmlgBQ4TWaUudE5edD5Y0Fx4LQQ6LnmNjfBBcfS14s4Q9MmiD9YQZZSyKTu9UoeR3SpQkGEVvkI6t7rhtyheMqwtJiCxmitCcKVm8RhLrjgEIq2wbBTegINEOKFQKpf3IHsolssm2UuebYpaXxxB68swMwDdBC-By51aTdAaZpJWGiviqZiCNnuzvuKNfhnrZVk482ctrBdu0AgGj-YxKsnVEQozXvCHiojnQE7YfJW048ctYUBgti0wpKvNI2_PbavT11W8cD0x093uQhARZtSBazv4mkqtbPpdv6GSzIE6PHETfKIxJIMaDzLJKAnbOHCEquHfYD1KouZO93Cw.IopkTsaLXan0zWOW.jWxoHQPORSNVHQKfypBQ23BWtq3hzwkDDasd65asd7a8sfg8sd8gsd78gs9gdf8asdc9asdfdsfFXw-hfLA1uhCIeZebRNcTzmVcR_Kd0g75tCzH8FJw4TXMPvQ9Qg9NcJI1JsA_DLC1B9m0hwPXtUib0Pz7k5Z2l7fwCUUfFfT4VNiPrhsuz35XlbNJc1fq1kfN88f5sGZ0UocYwl_CtPf-0FwMeGJkhyyKIWAguV0z5FsfaVWojDPcGkw5JqILUwYxKZUW3mSORI5tXrgVloLoF48xaFoXpK5T2xPHfSaUZMJBsFMK24MdDRgLIfy6XS-21upJsi30O6yyc96A1vYYpk-eD871WC9156AlB3BskCsmgPKRSjPaDQ6Dfuc_xDR4ZLYb5XSaFtEC8q5eGeq-N2DjS0eDQbsUyMFY8ddY7BVNWIv0X1_HRKz6Nilrveimmc4OfaQ3aTHj32VDkxJb5BZgylEgLtaO_HRnqjnPD1Ic-XlxH0oXLgVm2aN3SSdXuEr3BdtCoRtnGfAkLAlK686L-3Ryo2Xg1oR61gNJXBljeFQVeTeUSNuYBKyc_swv4pwBUW_Ff_iOiR_ddhMuzqattTEtGxyXDKIVls3tDoyerJsD5e-_igpKkw5cks9Il6XI1I0Mq2jnso7xFeZEBztt3qcXJ5w8OdV1Qsc79SnAIA8yF9K_8zwZvMfFU5ODJSkvY56lReBiHDImQfDiImkgShDSKu-4y8IP10Ba3jr55b7rebgk3fO9yV9JcZOx9C2JtAHKFaTVCYz2YRA3fChUXlRHcqJfc2cYYAx5wD9fJLR4FiVkgkapaNadYT0pc4LPnylyijtUXgxL7tpDG4i9yJiQ1hT3kHV4o9NZeXyPV-VDN2XWeCOEYhpXASnj7nyRpzH4wPmD9xa6N-4mDzqDVXel7c527eecN7ZfU3MPXJ2fHnTGTzDjPCCPG1Ur0LE-9CJMWMMxbFDV9RR6paKMU8fno-cgczR-HZsWIgGzXudYEyb03OVDmRgdKxW_oWL8yWx0KEMtibHH.5jIZnrXB7RFLn3LS1bJqGA",
"IdToken":"eyJraWQiOiJlZFRQVFU0cXNOdFQyOEd2TWlXakg1aUExZjZFOVwvekw3OEZLYzdWU1VoWT0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJlYTkwZDYyOS0xYjc1LTRjZmItOGQ5ZC1kZGZlYmFkZmVkZjMiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImlzcyI6Imh0dHBzOlwvXC9jb2dadfgsdf6asdf87sd6fsd8f89fjpITrZUOH58mhfm-ToGQznHcWxd5I48W-uHckz1F9dLP9YLZpI0e3BGPPPeEOf2lAIa0dSfzKhl-SZgSLRBd5qX066jx1_6SvnTMpDgRE9JZmFM_n3cI2_jGoShxUwr7NpGaUCo2r2LPXx9Rs-KqmU33mqTFD8F-CezracE9xuAuDiTNCwlBA9_LB1FPQhvzkkgSR5vouIyUYzg"
},
"..."
}

包含三个部分:

  1. AccessToken—用于检查对Cognito认证api的访问
  2. RefreshToken—用于刷新访问令牌
  3. IdToken-承载JWT令牌,通常由CUP (Congito用户池)之外的服务使用

AccessToken&RefreshToken正在被撤销,但是JWT ID令牌(API GW使用的)没有被撤销。

这是由AWS员工在这个GitHub问题中确认的:

因为IdToken被表示为JSON Web Key Token,它是用秘密或私钥/公钥对签名的,这意味着即使你撤销了IdToken,也没有办法撤销分布式公钥。

其他人也指出了这个问题,这里,这里&例如:

这并不是Amazon的错,因为JWT令牌的性质意味着它们是无状态的。授权服务器不需要存储任何状态来验证JWT令牌——验证令牌持有者的授权只需要令牌本身。

这可能在文档的另一部分中更清楚地突出显示:

如果使用任何验证令牌签名和过期的JWT库对吊销令牌进行验证,则吊销令牌仍然有效。


从本质上讲,坏消息是您已经达到了Amazon Cognito的限制。

稍微好的消息是,如果您的解决方案允许,您可以将ID令牌的有效期设置为Cognito ID令牌的至少1小时。虽然Cognito配额页面提到ID令牌至少需要5分钟,但控制台实际上会抛出一个Cannot be greater than refresh token expiration.错误,持续5分钟。您必须将其设置为最小刷新令牌过期持续时间,当前为60分钟。

更好的说法是[AdminUserGlobalSignOut][9]的文档是这样写的:

以管理员身份注销所有设备上的用户。它还会使发给用户的所有刷新令牌失效。用户当前的访问和Id令牌在到期之前保持有效。访问和Id令牌在发出一小时后过期。

好消息是,一个AWS Amplify贡献者在2月份给出了一个更新,他们正在研究这个问题(同样的"修复")。(希望作为Congito外部的服务应用于API Gateway)。

"best"消息是,有可能实现"真实"。自己撤销令牌,以防止ID令牌继续被使用。你需要有一个自定义API网关Lambda授权器(本指南也可能有用)来验证token与Cognito,但随后也检查令牌,看看它是否被撤销,例如检查blocklistDynamoDB表。在我的回答中阅读更多关于方法的信息。

直到亚马逊允许你"撤销"ID令牌也管理与被撤销的刷新令牌相关联的ID令牌添加到他们一方的块列表中,其他服务可以使用该列表进行验证,您必须自己实现。

相关内容

  • 没有找到相关文章

最新更新