首页 > 解决方案 > 带有公钥的 Microsoft Graph AccessToken 签名验证

问题描述

我需要从 Microsoft Graph API 验证令牌的签名。我知道使用的签名密钥的指纹在 JWT 的标头中:

在此处输入图像描述

并且它对应于您可以从众所周知的端点获得的密钥:

https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys

它返回一个密钥数组,包括令牌的签名密钥: 在此处输入图像描述

我的计划是将密钥列表存储在缓存中,以便在需要进行验证时查找令牌的正确签名密钥。但是我知道有时键可能会旋转。

由于没有太多关于此的文档,我的问题分为多个部分:

标签: authenticationoauthjwtmicrosoft-graph-apiopenid

解决方案


已在各种库中为您实现密钥翻转;一个合理的策略是使用其中一个而不是自己滚动。

来自的 JSON 文档https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys符合 JSON Web Key (JWK) 规范 ( RFC 7517 )。规范没有规定keys数组中键的顺序:

参数的值"keys"是一个 JWK 值数组。默认情况下,数组中 JWK 值的顺序并不意味着它们之间的优先顺序,尽管 JWK 集的应用程序可以根据需要选择为顺序指定含义。

Microsoft 的密钥翻转实施似乎将较新的密钥添加到列表顶部。对此没有书面保证,我们不建议依赖它。至于键何时从列表中删除,同样没有发布的规范。如果证书被撤销或过期,则不能用于验证签名。常识表明它应该在那个时间点从列表中删除。微软的关键翻转文档指出

在紧急情况下,[钥匙]可以立即翻转。

翻译:您应该多久返回一次已发布的“主”密钥列表的https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys决定取决于无法在您的应用程序中验证令牌的重要性/后果。

x5c是一个数组,因为它代表一个证书链。Microsoft 的实现使用单个证书(链的长度 = 1),但没有什么能阻止他们在未来某个时间点使用更长的链。实际上,他们不太可能这样做,因为这会影响许多不合格的应用程序以及他们自己的库。


推荐阅读