authentication - 带有公钥的 Microsoft Graph AccessToken 签名验证
问题描述
我需要从 Microsoft Graph API 验证令牌的签名。我知道使用的签名密钥的指纹在 JWT 的标头中:
并且它对应于您可以从众所周知的端点获得的密钥:
https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys
我的计划是将密钥列表存储在缓存中,以便在需要进行验证时查找令牌的正确签名密钥。但是我知道有时键可能会旋转。
由于没有太多关于此的文档,我的问题分为多个部分:
这是一个合理的策略吗?
新密钥是否会附加到已知端点的列表中?我假设这个列表会随着时间的推移而增长,所以如果令牌需要它,我总是可以得到一个旧的密钥?除了刷新我的缓存之外,它还需要使用可用的密钥进行补水。
旧键在什么时候会从这个列表中删除?我假设必须有一个时间或计数截止。
似乎最新的键是第一条记录并且按降序排序?
为什么 x5c 是一个数组?每条记录不应该只有一个签名密钥吗?我假设我应该只使用 .x5c[0] 但在什么情况下这里会有多个项目?
解决方案
已在各种库中为您实现密钥翻转;一个合理的策略是使用其中一个而不是自己滚动。
来自的 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),但没有什么能阻止他们在未来某个时间点使用更长的链。实际上,他们不太可能这样做,因为这会影响许多不合格的应用程序以及他们自己的库。
推荐阅读
- c# - 如何将多个不同的数据库对象传递给不同表中的同一个视图
- python - 为什么 IDLE 会自动缩进大量的四个制表符?每个制表符似乎是 8 个空格,因此缩进 32 个空格
- amazon-web-services - AWS 上的灾难恢复 Kops Kubernetes 主节点
- vim - 使用 GNU Screen 使用 Vim 到 R 执行超出原始屏幕视图的代码
- powershell - Import-StartLayout 对当前用户没有任何作用
- php - 在 Raspbian 上编写 Apache HTML
- javascript - 减少一组谓词函数
- c - 为什么 strtok 不能正确分隔这个字符串?C
- javascript - 获取文本区域的真实值
- html - 如何获取 webbrowser 的下拉菜单项列表?