Search code examples
pythonazure-active-directoryazure-ad-b2cazure-ad-msal

AAD B2C MSAL for python Token Validation without the public key in JWKS_URI


When trying to validate my token using this code from MSAL library https://github.com/AzureAD/microsoft-authentication-library-for-python

cache = _load_cache()  # This web app maintains one cache per session

    cca = _build_msal_app(cache=cache)

    accounts = cca.get_accounts()

    if accounts:  # So all account(s) belong to the current signed-in user

        result = cca.acquire_token_silent(scope, account=accounts[0])

        _save_cache(cache)

        return result

I grab the id_token from the returned dictionary which is base64 encoded. And it returns a header of:

{

  "typ": "JWT",

  "alg": "RS256",

  "kid": "X5eXk4xyojNFum1kl2Ytv8dlNP4-c57dO6QGTVBwaNk"

}

Payload of:

{

  "exp": 1664743047,

  "nbf": 1664739447,

  "ver": "1.0",

  "iss": "https://******.b2clogin.com/*******/v2.0/",

  "sub": "*******",

  "aud": "22b52070-255a-4de8-b9ac-f6f37498e6bb",

  "nonce": "a0da49a5916f3cf9a4fc7432782dba443f7a0e5dafce19f8c919b3e6a1ef67f6",

  "iat": 1664739447,

  "auth_time": 1664699840,

  "oid": "*******",

  "given_name": "Gabriel",

  "tfp": "B2C_1_susi"

}

It is my understanding that there should be a key of "x5t" containing the public key I can use to validate the signature.

When I run the code below to verify my signature it comes back as invalid, which confuses me because I know the token came from AAD.

from azure_ad_verify_token import verify_jwt

azure_ad_app_id = '*******'

azure_ad_issuer = 'https://exampletenant.b2clogin.com/0867afa-24e7-40e9-9d27-74bb598zzzzc/v2.0/'

azure_ad_jwks_uri = 'https://exampletenant.b2clogin.com/exampletenant.onmicrosoft.com/B2C_1_app_sign_in/discovery/v2.0/keys?appid=*********'

payload = verify_jwt(

    token='<AZURE_JWT_TO_VERIFY_HERE>',

    valid_audiences=[azure_ad_app_id],

    issuer=azure_ad_issuer,

    jwks_uri=azure_ad_jwks_uri,

    verify=True,

)

Solution

  • You should not need to use Python-Jose like you did in your self-answer.

    The recent versions of MSAL Python library are able to also return a id_token_claims from the returned dictionary. Those claims are payload that has already been validated for you, so you do not need to.