Microsoft AD JWT Won't Decode

1k Views Asked by At

I've used the python code sample below from Microsoft to try and decode access and identity tokens (JWT) from Microsoft AD. I've tried every method I can find online for doing this and no matter what I keep getting this error:

  File "C:\Users\Connor Johnson\AppData\Local\Programs\Python\Python37\lib\site-packages\jwt\api_jwt.py", line 92, in decode
    jwt, key=key, algorithms=algorithms, options=options, **kwargs
  File "C:\Users\Connor Johnson\AppData\Local\Programs\Python\Python37\lib\site-packages\jwt\api_jws.py", line 156, in decode
    key, algorithms)
  File "C:\Users\Connor Johnson\AppData\Local\Programs\Python\Python37\lib\site-packages\jwt\api_jws.py", line 223, in _verify_signature
    raise InvalidSignatureError('Signature verification failed')
jwt.exceptions.InvalidSignatureError: Signature verification failed

I've tried different encoding-centered solutions to no avail, and at this point all I can figure is that it's an AD configuration issue. If I need to provide specific AD settings, let me know.

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

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

    # get Microsoft Azure public key


def get_public_key_for_token(kid):
  response = requests.get(
  'https://login.microsoftonline.com/common/.well-known/openid-configuration',
  ).json()

  jwt_uri = response['jwks_uri']
  response_keys = requests.get(jwt_uri).json()
  pubkeys = response_keys['keys']

  public_key = ''

  for key in pubkeys:
      # found the key that matching the kid in the token header
      if key['kid'] == kid:
          # construct the public key object
          mspubkey = str(key['x5c'][0])
          cert_str = PEMSTART + mspubkey + PEMEND
          cert_obj = load_pem_x509_certificate(str.encode(cert_str), default_backend())
          public_key = cert_obj.public_key()

  return public_key

# decode the given Azure AD access token


def aad_access_token_decoder(access_token):
  header = jwt.get_unverified_header(access_token)
  print(header['kid'])
  public_key = get_public_key_for_token(header['kid'])
  # the value of the databricks_resource_id is as defined above
  databricks_resource_id=<APP ID>
  decoded=jwt.decode(access_token, key = public_key, algorithms = 'RS256',
      audience = databricks_resource_id)

  for key in decoded.keys():
      print(key + ': ' + str(decoded[key]))

aad_access_token_decoder(<JWT BEARER TOKEN IN STRING>)

1

There are 1 best solutions below

1
On

You have a misconfiguration on your app registration. You issuer url, audience, or something, is set up wrong. I can't tell you more without knowing a lot more about the app registration and code setup.

I'm pretty sure that "common" in the oidc config url only works for multi-tenant apps. If your app is not multi tenant you might try substituting your tenant id right there.