¿Cómo verificar JWT id_token producido por MS Azure AD?

Tengo una aplicación web angularjs SPA que utiliza ADAL-JS (y adal-angular). Está configurado para autenticar vs nuestro AD corporativo en MS Azure. El flujo de inicio de sesión parece funcionar correctamente, y el SPA recibe un id_token.

Luego, cuando el usuario hace clic en un botón, el SPA realiza una solicitud a una API REST que estoy hospedando en AWS API Gateway. Estoy pasando el id_token en el encabezado Authorization: Bearer . La puerta de enlace de la API recibe el encabezado según lo previsto, y ahora tiene que determinar si el token dado es bueno o no para permitir o denegar el acceso.

Tengo un token de muestra y se analiza correctamente en https://jwt.io/ pero hasta ahora no he podido encontrar la clave pública o el certificado que debería usar para verificar la firma. He mirado en

  • 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 (para obtener el 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

Creo que debería usar el valor de la propiedad x5c de la clave en https://login.microsoftonline.com/common/discovery/keys que coincida con las propiedades kid y x5t de JWT id_token (actualmente a3QN0BZS7s4nN-BdrjbF0Y_LdMM , que lleva a una valor x5c que comienza con “MIIDBTCCAe2gAwIBAgIQY …”). Sin embargo, la página https://jwt.io/ informa “Firma no válida” (también intenté ajustar el valor de la clave con “—– BEGIN CERTIFICATE —–” y “—– END CERTIFICATE- —- “).

Además, ¿existe una biblioteca (posiblemente Python) que pueda facilitar la verificación de un id_token dado como en el caso anterior (para que no tenga que ir a buscar la clave de firma sobre la marcha?) … Lo mejor que puedo hacer ¿podría encontrar ( ADAL para python ) no parece proporcionar esta característica?

    La mejor solución que pude juntar hasta ahora:

    Obtenga el certificado (el primer valor en la x5c propiedades x5c ) desde https://login.microsoftonline.com/common/discovery/keys o https://login.microsoftonline.com/common/discovery/v2.0/keys , haciendo coincidir kid y x5t del id_token.

    Envuelva el certificado en -----BEGIN CERTIFICATE-----\n COMIENCE EL -----BEGIN CERTIFICATE-----\n \n-----END CERTIFICATE----- TERMINE EL \n-----END CERTIFICATE----- (las nuevas líneas parecen importar), y use el resultado como clave pública (en junto con el id_token, en https://jwt.io/ ).

    Por supuesto, es probable que su caso de uso real tenga algún progtwig que valide la JWT id_tokens entrante, por lo que su objective no será simplemente validar el token a través de la interfaz de usuario web en https://jwt.io/ .

    Por ejemplo, en Python , necesito algo como esto:

     #!/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." 

    Para obtener una lista de las bibliotecas de JWT en varios idiomas, consulte el sitio de JWT . Estoy usando pyjwt y su dependencia de criptografía (que tiene dependencias binarias, por lo que debe comstackrse y empaquetarse para el sistema operativo de destino).

    Y luego, por supuesto, puede verificar detalles adicionales, como las reclamaciones que se recomiendan aquí .

    Para una solución JVM, usar com.nimbusds:numbus-jose-jwt:4.29 es la forma más directa de analizar y validar un id_token RSA256 firmado. El siguiente código de Scala analiza el token JWT con una clave web JSON:

      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)) 

    Su aplicación aún necesitaría obtener el conjunto de claves web JSON de la clave de discovery/v2.0/key Az2 de Active Directory B2C para obtener el conjunto de claves potencialmente utilizadas por AAD B2C. Es probable que esto deba ser almacenado en caché y tener un TTL de no más de 24 horas para mayor eficiencia.