Search code examples
azureazure-ad-msalmsal

how to get v2 type token using msal python


I am trying to get a v2 type token using the msal library for python

my code is as in below

global_app = msal.ClientApplication(
    os.getenv('CLIENT_ID'),
    authority=os.getenv('AUTHORITY'),  # For Entra ID or External ID
    oidc_authority=os.getenv('OIDC_AUTHORITY'),  # For External ID with custom domain
    client_credential=os.getenv('CLIENT_SECRET') or None,  # Treat empty string as None
    token_cache=global_token_cache,  # Let this app (re)use an existing token cache.
        # If absent, ClientApplication will create its own empty token cache
    )

result = global_app.acquire_token_by_username_password(
            os.getenv("USERNAME"), password, scopes=scopes)

Additionally i have tried to set and unset the scopes as User.Read.

I have also set the accesstokentype in the Azure manifests to v2.

However when i run the above, i still get the token with issuer as https://sts.... which is different from my issue which is of the type https://login.microsoftonline.com/{TENANT}

I need assistance in getting the correct v2 token back


Solution

  • Note that, User.Read is Microsoft Graph permission for which version 2.0 tokens are not yet supported. Refer this MS Q&A by Sivakumar-MSFT.

    I registered one application and set accessTokenAcceptedVersion in Azure Manifest to v2 as below:

    enter image description here

    When I decoded the token generated with User.Read scope, its version is 1.0 :

    enter image description here

    To get v2 type token, you need to create new custom scope by exposing an API like this:

    enter image description here

    Make sure to add this custom scope in API permissions tab and grant admin consent to it as below:

    enter image description here

    Now, generate the token by changing scope parameter to custom scope value in your python code:

    import msal
    from dotenv import load_dotenv
    import os
    
    load_dotenv()
    
    client_id = os.getenv('CLIENT_ID')
    authority = os.getenv('AUTHORITY')
    oidc_authority = os.getenv('OIDC_AUTHORITY')
    client_secret = os.getenv('CLIENT_SECRET') or None
    username = os.getenv("USERNAME")
    password = os.getenv("PASSWORD")
    scopes = ["api://appId/custom.read"]
    
    global_app = msal.ClientApplication(
        client_id,
        authority=authority,
        client_credential=client_secret,
        token_cache=None
    )
    
    result = global_app.acquire_token_by_username_password(
        username=username,
        password=password,
        scopes=scopes
    )
    
    if "access_token" in result:
        print("Access token:", result["access_token"])
    else:
        print("Failed to acquire token.")
        print(result.get("error"))
        print(result.get("error_description"))
    

    Response:

    enter image description here

    To confirm that, I decoded the token in jwt.ms website where token generated with version 2.0 successfully as below:

    enter image description here