[英]How to verify JWT id_token produced by MS Azure AD?
我有一个angularjs SPA网络应用程序,它使用ADAL-JS (和adal-angular)。 它设置为在MS Azure中对我们的公司AD进行身份验证。 登录流程似乎正常,SPA收到id_token。
接下来,当用户单击按钮时,SPA会向我在AWS API Gateway上托管的REST API发出请求。 我在Authorization: Bearer <id_token>
标Authorization: Bearer <id_token>
传递了id_token。 API网关按预期接收标头,现在必须确定给定标记是否良好以允许或拒绝访问。
我有一个示例令牌,它在https://jwt.io/上正确解析但我到目前为止未能找到我应该用来验证签名的公钥或证书。 我查了一下:
我想我应该使用https://login.microsoftonline.com/common/discovery/keys中密钥的x5c属性的值来匹配来自JWT id_token的kid和x5t属性(当前是a3QN0BZS7s4nN-BdrjbF0Y_LdMM
,这导致了x5c值以“MIIDBTCCAe2gAwIBAgIQY ...”开头。 但是, https://jwt.io/页面报告“无效签名”(我也尝试用“----- BEGIN CERTIFICATE -----”和“----- END CERTIFICATE-”包装密钥值----“)。
另外,是否有一个(可能是python)库可以帮助验证给定的id_token,如上所述(这样我就不必自己去抓取签名密钥了?)...最好的我可以找到( ADAL for python )似乎没有提供此功能?
到目前为止我可以组合的最佳解决方案:
从https://login.microsoftonline.com/common/discovery/keys
或https://login.microsoftonline.com/common/discovery/v2.0/keys
获取证书 ( x5c
属性数组中的第一个值) ,匹配kid
和x5t
从id_token。
将证书包装在-----BEGIN CERTIFICATE-----\\n
和\\n-----END CERTIFICATE-----
(新行似乎很重要),并将结果用作公钥(在与id_token结合,在https://jwt.io/上 。
当然,您的实际用例可能是让某些程序验证传入的JWT id_tokens,因此您的目标不是简单地通过https://jwt.io/上的Web UI获取令牌。
例如, 在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."
有关各种语言的JWT库列表,请参阅JWT站点 。 我正在使用pyjwt及其加密依赖关系(它具有二进制依赖关系,因此需要为目标操作系统构建和打包)。
然后,当然,您可以验证其他详细信息,例如 此处推荐 的声明 。
对于JVM解决方案,使用com.nimbusds:numbus-jose-jwt:4.29
是解析和验证签名RSA256 id_token的最直接方式。 以下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))
您的应用程序仍需要动态地从Azure Active Directory B2C discovery/v2.0/key
获取JSON Web密钥集,以获取AAD B2C可能使用的密钥集。 这可能应该被缓存并且TTL不超过24小时以提高效率。
另外,是否有一个(可能是python)库可以帮助验证给定的id_token,如上所述(这样我就不必自己去抓取签名密钥了?)...最好的我可以找到(ADAL for python)似乎没有提供此功能?
对于它的价值, MSAL Python ,它是ADAL Python的后继者,验证了引擎盖下的id令牌,并为您的应用程序的id令牌提供已解码的声明 。 因此,您的应用程序 - 它刚刚通过MSAL Python获取该ID令牌 - 可以在本地使用它。
接下来,当用户单击按钮时,SPA会向我在AWS API Gateway上托管的REST API发出请求。 我在
Authorization: Bearer <id_token>
标Authorization: Bearer <id_token>
传递了id_token。 API网关按预期接收标头,现在必须确定给定标记是否良好以允许或拒绝访问。
通常,id token不会在“ Authorization: Bearer <id_token>
header”上用于发送给第三方以进行授权。 因人而异。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.