0

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

Connor
  • 35
  • 2
  • 8

1 Answers1

0

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.

Derek Gusoff
  • 780
  • 4
  • 6
  • Sorry, not your tenant id but your directory id. Something like: https://login.microsoftonline.com/32c5fbcd-F000-447c-a5a7-c35b3bcc646c/.well-known/openid-configuration – Derek Gusoff Aug 02 '20 at 02:36