【问题标题】:Microsoft Graph AccessToken Signature Verification with Public Keys带有公钥的 Microsoft Graph AccessToken 签名验证
【发布时间】:2020-07-02 05:44:23
【问题描述】:
我需要从 Microsoft Graph API 验证令牌的签名。我知道使用的签名密钥的指纹在 JWT 的标头中:
并且它对应于您可以从众所周知的端点获得的密钥:
https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys
它返回一个密钥数组,包括令牌的签名密钥:
我的计划是将密钥列表存储在缓存中,以便在需要进行验证时查找令牌的正确签名密钥。但是我知道有时键可能会旋转。
由于没有太多关于此的文档,我的问题分为多个部分:
这是一个合理的策略吗?
新密钥是否被附加到已知端点的列表中?我假设这个列表会随着时间的推移而增长,所以如果令牌需要它,我总是可以得到一个旧的密钥?除了刷新我的缓存之外,它还需要使用可用的密钥进行补水。
较旧的密钥在什么时候会从该列表中删除?我假设必须有一个时间或计数截止。
好像最新的key是第一条记录,是降序排列的?
为什么 x5c 是一个数组?每条记录不应该只有一个签名密钥吗?我假设我应该只使用 .x5c[0] 但在什么情况下这里会有多个项目?
【问题讨论】:
标签:
authentication
oauth
jwt
microsoft-graph-api
openid
【解决方案1】:
Key rollover 已在各个库中为您实现;一个合理的策略是使用其中一个而不是自己滚动。
来自https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys 的 JSON 文档符合 JSON Web Key (JWK) 规范 (RFC 7517)。规范没有规定 keys 数组中键的顺序:
"keys" 参数的值是一个 JWK 值数组。经过
默认情况下,数组中 JWK 值的顺序并不意味着
它们之间的优先顺序,尽管 JWK 集的应用
可以为他们的目的选择为订单分配一个含义,如果
想要的。
Microsoft 的密钥翻转实施似乎将较新的密钥添加到列表顶部。对此没有书面保证,我们不建议依赖它。
至于键何时从列表中删除,同样没有发布的规范。如果证书被撤销或过期,则不能用于验证签名。常识表明它应该在那个时间点从列表中删除。微软的key rollover doc 指出
在紧急情况下,[钥匙]可以立即翻转。
翻译:您应该多久返回到https://login.microsoftonline.com/[TENANT-ID]/discovery/v2.0/keys 上发布的“主”密钥列表的决定取决于无法在您的应用中验证令牌的重要性/后果。
x5c 是一个数组,因为它代表一个certificate chain。 Microsoft 的实现使用单个证书(链的长度 = 1),但没有什么能阻止他们在未来某个时间点使用更长的链。实际上,他们不太可能这样做,因为这会影响许多不合格的应用程序以及它们自己的库。