如何验证 MS Azure AD 生成的 JWT id_token? [英] How to verify JWT id_token produced by MS Azure AD?

查看:54
本文介绍了如何验证 MS Azure AD 生成的 JWT id_token?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 angularjs SPA 网络应用程序,它使用 ADAL-JS(和adal-angular).它设置为在 MS Azure 中与我们的公司 AD 进行身份验证.登录流程似乎工作正常,SPA 收到一个 id_token.

I have an angularjs SPA web app which uses ADAL-JS (and adal-angular). It's set up to authenticate vs our corporate AD in MS Azure. The log-in flow seems to work correctly, and the SPA receives an id_token.

接下来,当用户单击按钮时,SPA 会向我托管在 AWS API Gateway 上的 REST API 发出请求.我在 Authorization: Bearer 标头上传递 id_token.API 网关按预期接收标头,现在必须确定给定令牌是否良好,以允许或拒绝访问.

Next, when the user clicks a button, the SPA makes a request to a REST API I am hosting on AWS API Gateway. I am passing the id_token on the Authorization: Bearer <id_token> header. The API Gateway receives the header as intended, and now has to determine if the given token is good or not to either allow or deny access.

我有一个示例令牌,它在 https://jwt.io/ 上正确解析,但我有far 未能找到我应该用来验证签名的公钥或证书.我看过了:

I have a sample token, and it parses correctly on https://jwt.io/ but I have so far failed to find the Public Key or Certificate I should use to verify the signature. I have looked in:

  • https://login.microsoftonline.com/{tenantid}/federationmetadata/2007-06/federationmetadata.xml
  • https://login.microsoftonline.com/{tenantId}/discovery/keys
  • https://login.microsoftonline.com/common/.well-known/openid-configuration (to get the jwks_uri)
  • https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration
  • https://login.microsoftonline.com/common/discovery/keys
  • https://login.microsoftonline.com/common/discovery/v2.0/keys

认为我应该使用 https://login.microsoftonline.com/common/discovery/keys 匹配来自 JWT id_token 的 Kid 和 x5t 属性(当前为 a3QN0BZS7s4nN-BdrjbF0Y_LdMM,这导致 x5c 值以MIIDBTCCAe2gAwIBAgIQY..."开头).但是,https://jwt.io/ 页面报告无效签名"(我也尝试用-----开始证书-----"和-----结束证书-----").

I think I should use the value of the x5c property of the key in https://login.microsoftonline.com/common/discovery/keys matching the kid and x5t properties from the JWT id_token (currently a3QN0BZS7s4nN-BdrjbF0Y_LdMM, which leads to an x5c value starting with "MIIDBTCCAe2gAwIBAgIQY..." ). However, the https://jwt.io/ page reports "Invalid Signature" (I also tried wrapping the key value with "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----").

另外,是否有一个(可能是 python)库可以像上面的例子一样促进给定 id_token 的验证(这样我就不必亲自去获取签名密钥?)...我能找到的最好的(ADAL for python)似乎没有提供这个功能?

Also, is there a (possibly python) library that can facilitate the verification of a given id_token as in the case above (so that I won't have to go grab the signing key on the fly myself?)... The best I could find (ADAL for python) doesn't seem to provide this feature?

推荐答案

目前我能想到的最佳解决方案:

The best solution I could put together so far:

获取证书(x5c 属性数组中的第一个值) 或 https://login.microsoftonline.com/common/discovery/v2.0/keys,匹配 kidx5t来自 id_token.

Grab the certificate (the first value in the x5c property array) from either https://login.microsoftonline.com/common/discovery/keys or https://login.microsoftonline.com/common/discovery/v2.0/keys, matching kid and x5t from the id_token.

将证书包装在-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----(换行符似乎很重要),并将结果用作公钥(结合 id_token,在 https://jwt.io/ ).

Wrap the certificate in -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- (the newlines seem to matter), and use the result as Public Key (in conjunction with the id_token, on https://jwt.io/ ).

当然,您的实际用例可能是让某个程序验证传入的 JWT id_tokens,因此您的目标不是简单地通过 https://jwt.io/.

Of course, your actual use case will likely be to have some program validate the incoming JWT id_tokens, so your goal won't be to simply get the token to validate through the web UI on https://jwt.io/.

例如,在python中,我需要这样的东西:

For instance, in python, I need something like this:

#!/usr/bin/env python

import jwt
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.backends import default_backend

PEMSTART = "-----BEGIN CERTIFICATE-----
"
PEMEND = "
-----END CERTIFICATE-----
"

mspubkey = "The value from the x5c property"
IDTOKEN = "the id_token to be validated"
tenant_id = "your tenant id"

cert_str = PEMSTART + mspubkey + PEMEND
cert_obj = load_pem_x509_certificate(cert_str, default_backend())
public_key = cert_obj.public_key()

decoded = jwt.decode(IDTOKEN, public_key, algorithms=['RS256'], audience=tenant_id)
if decoded:
    print "Decoded!"
else:
    print "Could not decode token."

有关各种语言的 JWT 库列表,请参阅JWT 站点.我正在使用 pyjwt 及其 cryptography 依赖(具有二进制依赖,因此需要为目标操作系统构建和打包).

For a list of JWT libraries in various languages, see the JWT Site. I'm using pyjwt, and its cryptography dependency (which has binary dependencies, so needs to be built and packaged for the target OS).

然后,当然,您可以验证其他详细信息,例如声明作为此处推荐.

And then, of course, you can verify additional details such as the claims as recommended here.

这篇关于如何验证 MS Azure AD 生成的 JWT id_token?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆