简体   繁体   English

如何验证MS Azure AD生成的JWT id_token?

[英]How to verify JWT id_token produced by MS Azure AD?

I have an angularjs SPA web app which uses ADAL-JS (and adal-angular). 我有一个angularjs SPA网络应用程序,它使用ADAL-JS (和adal-angular)。 It's set up to authenticate vs our corporate AD in MS Azure. 它设置为在MS Azure中对我们的公司AD进行身份验证。 The log-in flow seems to work correctly, and the SPA receives an id_token. 登录流程似乎正常,SPA收到id_token。

Next, when the user clicks a button, the SPA makes a request to a REST API I am hosting on AWS API Gateway. 接下来,当用户单击按钮时,SPA会向我在AWS API Gateway上托管的REST API发出请求。 I am passing the id_token on the Authorization: Bearer <id_token> header. 我在Authorization: Bearer <id_token>Authorization: Bearer <id_token>传递了id_token。 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. API网关按预期接收标头,现在必须确定给定标记是否良好以允许或拒绝访问。

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. 我有一个示例令牌,它在https://jwt.io/上正确解析但我到目前为止未能找到我应该用来验证签名的公钥或证书。 I have looked in: 我查了一下:

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..." ). 我应该使用https://login.microsoftonline.com/common/discovery/keys中密钥的x5c属性的值来匹配来自JWT id_token的kid和x5t属性(当前是a3QN0BZS7s4nN-BdrjbF0Y_LdMM ,这导致了x5c值以“MIIDBTCCAe2gAwIBAgIQY ...”开头。 However, the https://jwt.io/ page reports "Invalid Signature" (I also tried wrapping the key value with "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----"). 但是, https://jwt.io/页面报告“无效签名”(我也尝试用“----- BEGIN CERTIFICATE -----”和“----- END CERTIFICATE-”包装密钥值----“)。

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? 另外,是否有一个(可能是python)库可以帮助验证给定的id_token,如上所述(这样我就不必自己去抓取签名密钥了?)...最好的我可以找到( ADAL for python )似乎没有提供此功能?

The best solution I could put together so far: 到目前为止我可以组合的最佳解决方案:

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. https://login.microsoftonline.com/common/discovery/keyshttps://login.microsoftonline.com/common/discovery/v2.0/keys 获取证书x5c属性数组中的第一个值) ,匹配kidx5t从id_token。

Wrap the certificate in -----BEGIN CERTIFICATE-----\\n and \\n-----END CERTIFICATE----- (the newlines seem to matter), and use the result as Public Key (in conjunction with the id_token, on https://jwt.io/ ). 将证书包装-----BEGIN CERTIFICATE-----\\n\\n-----END CERTIFICATE----- (新行似乎很重要),并将结果用作公钥(在与id_token结合,在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/ . 当然,您的实际用例可能是让某些程序验证传入的JWT id_tokens,因此您的目标不是简单地通过https://jwt.io/上的Web UI获取令牌。

For instance, in python , I need something like this: 例如, 在python中 ,我需要这样的东西:

#!/usr/bin/env python

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

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

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."

For a list of JWT libraries in various languages, see the JWT Site . 有关各种语言的JWT库列表,请参阅JWT站点 I'm using pyjwt , and its cryptography dependency (which has binary dependencies, so needs to be built and packaged for the target OS). 我正在使用pyjwt及其加密依赖关系(它具有二进制依赖关系,因此需要为目标操作系统构建和打包)。

And then, of course, you can verify additional details such as the claims as recommended here . 然后,当然,您可以验证其他详细信息,例如 此处推荐 的声明

For a JVM solution, using com.nimbusds:numbus-jose-jwt:4.29 is the most straight forward way to parse and validate a signed RSA256 id_token. 对于JVM解决方案,使用com.nimbusds:numbus-jose-jwt:4.29是解析和验证签名RSA256 id_token的最直接方式。 The following Scala code parses the JWT token with a JSON Web Key: 以下Scala代码使用JSON Web Key解析JWT标记:

    val jwt = SignedJWT.parse(token)

    val n = new Base64URL("Your Modulus Component of RSA Key")
    val e = new Base64URL("AQAB")
    val rsaKey = new RSAKey.Builder(n, e).keyUse(KeyUse.SIGNATURE).algorithm(JWSAlgorithm.RS256).build()

    val verified = jwt.verify(new RSASSAVerifier(rsaKey))

Your application would still need to fetch the JSON Web Key Set from Azure Active Directory B2C discovery/v2.0/key dynamically to get the set of keys potentially used by AAD B2C. 您的应用程序仍需要动态地从Azure Active Directory B2C discovery/v2.0/key获取JSON Web密钥集,以获取AAD B2C可能使用的密钥集。 This should probably be cached and have a TTL of not more than 24 hours for efficiency. 这可能应该被缓存并且TTL不超过24小时以提高效率。

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? 另外,是否有一个(可能是python)库可以帮助验证给定的id_token,如上所述(这样我就不必自己去抓取签名密钥了?)...最好的我可以找到(ADAL for python)似乎没有提供此功能?

For what it's worth, MSAL Python , which is ADAL Python's successor, validates the id token under the hood, and provides you the decoded claims inside an id token for your app. 对于它的价值, MSAL Python ,它是ADAL Python的后继者,验证了引擎盖下的id令牌,并为您的应用程序的id令牌提供已解码的声明 So that your app - which just obtained that id token via MSAL Python - can consume it locally. 因此,您的应用程序 - 它刚刚通过MSAL Python获取该ID令牌 - 可以在本地使用它。

Next, when the user clicks a button, the SPA makes a request to a REST API I am hosting on AWS API Gateway. 接下来,当用户单击按钮时,SPA会向我在AWS API Gateway上托管的REST API发出请求。 I am passing the id_token on the Authorization: Bearer <id_token> header. 我在Authorization: Bearer <id_token>Authorization: Bearer <id_token>传递了id_token。 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. API网关按预期接收标头,现在必须确定给定标记是否良好以允许或拒绝访问。

Usually id token is not used "on the Authorization: Bearer <id_token> header" to send to 3rd party for authorization purpose. 通常,id token不会在“ Authorization: Bearer <id_token> header”上用于发送给第三方以进行授权。 YMMV. 因人而异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何验证 Azure Ad 生产的 JWT? - How to verify JWT produced by Azure Ad? Azure AD B2C在id_token之前使用“#”重定向 - Azure AD B2C Redirects with a “#” before the id_token 连接到 Azure AD 时如何创建客户端断言 JWT 令牌? - How to create Client Assertion JWT token when connecting to Azure AD? 如何在 Python Flask OpenID 中获取 id_token? - how to get id_token in Python Flask OpenID? Python 如何通过使用 oauthlib 的帐户身份验证获取 ID_Token 以与 Open ID Connect 一起使用 - Python how to obtain ID_Token to use with Open ID Connect from using account authentication with oauthlib 如何解码和验证 simple-jwt-django-rest-framework 令牌 - How to decode and verify simple-jwt-django-rest-framework token 如何使用Python在Azure AD中验证令牌 - How to validate token in Azure AD with Python 如何检索 id_token 以访问 Google Cloud Function? - How can I retrieve an id_token to access a Google Cloud Function? 谷歌 oauth2 id_token 与 refresh_token - google oauth2 id_token vs refresh_token 使用 pyJWT 和 Python 解码 Apple 的 id_token(登录) - Decode Apple's id_token (Signin) using pyJWT and Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM