使用 Public 密钥的 Microsoft Graph AccessToken 签名验证

Microsoft Graph AccessToken Signature Verification with Public Keys

我需要验证来自 Microsoft Graph API 的令牌签名。我知道所使用的签名密钥的指纹在此处 JWT 的 header 中:

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

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

其中 returns 一组密钥,包括令牌的签名密钥:

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

由于这方面的文档不多,我的问题分为多个部分:

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

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

The value of the "keys" parameter is an array of JWK values. By default, the order of the JWK values within the array does not imply an order of preference among them, although applications of JWK Sets can choose to assign a meaning to the order for their purposes, if desired.

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

in an emergency, [keys] could be rolled over immediately.

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

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