skip to Main Content

i need to implement a script to check if the azure token that i’m receiving from front end is an authentic token. Since i’m waiting front end devs to implement the SAP (Single app application), i’ve impelmented a simple script to generate a token:

import requests

client_id = "MY_CLIENT_ID"  
tenant_id = "MY_TENANT_ID"
client_secret = "MY_CLIENT_SECRET"
username = "mail"
password = "password"
scope = "https://graph.microsoft.com/.default"

token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"

data = {
    "grant_type": "password",
    "client_id": client_id,
    "client_secret": client_secret,
    "scope": scope,
    "username": username,
    "password": password,
}

# Request
response = requests.post(token_url, data=data)

if response.status_code == 200:
    token_response = response.json()
    access_token = token_response.get("access_token")
    print("Access Token:", access_token)

    # UserInfo
    user_info_url = "https://graph.microsoft.com/v1.0/me"
    headers = {"Authorization": f"Bearer {access_token}"}
    user_response = requests.get(user_info_url, headers=headers)

    if user_response.status_code == 200:
        user_info = user_response.json()
        print("Informazioni utente:")
        print(user_info)
    else:
        print("User error:")
        print(user_response.status_code, user_response.text)
else:
    print("Error")
    print(response.status_code, response.text)

With the above script i’m capable to get an access token.

Now, the script belove is the one that should check if the token is authentic:

import msal
import json

# Configuration
CLIENT_ID = "SAME_CLIENT_ID"  
CLIENT_SECRET = "SAME_SECRET"
TENANT_ID = "SAME_TENANT_ID"
RESOURCE = "api://graph.microsoft.com"

# Token Verification Function
def verify_token(access_token):
    try:
        # Initialize MSAL ConfidentialClientApplication
        app = msal.ConfidentialClientApplication(
            client_id=CLIENT_ID,
            client_credential=CLIENT_SECRET,
            authority=f"https://login.microsoftonline.com/{TENANT_ID}"
        )

        # Acquire a token on behalf of the user to validate the existing token
        result = app.acquire_token_on_behalf_of(
            user_assertion=access_token,
            scopes=[f"{RESOURCE}/.default"]
        )

        if "access_token" in result:
            print("Token is valid.")
            print("Token claims:", json.dumps(result.get("id_token_claims"), indent=2))
            return True
        else:
            print("Token validation failed:", result.get("error_description"))
            return False

    except Exception as e:
        print("An error occurred while verifying the token:", str(e))
        return False

token_to_validate = input("Enter the token to validate: ")

# Verify the token
is_valid = verify_token(token_to_validate)
if is_valid:
    print("The token is authentic.")
else:
    print("The token is not authentic.")

In output i have this message:

Token validation failed: AADSTS50013: Assertion failed signature validation. 
[Reason - Key was found, but use of the key to verify the signature failed., Thumbprint of key used by client: 'IDED_BY_ME', 
Found key 'Start=11/27/2024 09:04:39, End=11/27/2029 09:04:39', 
Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for 
app Id '00000000-0000-0000-0000-000000000000'. 
Review the documentation at https://docs.microsoft.com/en-us/graph/deployments 
to determine the corresponding service endpoint 
and https://docs.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL, 
such as 'https://graph.microsoft.com/beta/applications/00000000-0000-0000-0000-000000000000']. 
Trace ID: 01e09def-59ad-49a3-addc-721fdbc67000 
Correlation ID: 84b76158-1dc7-4932-88de-50bae5f8ac36 Timestamp: 2025-01-17 12:18:30Z
The token is not authentic.

I’m not understanding where is the error since i’m providing a token just created. I’ve verified that is working on https://jwt.ms/ and i’m following what is suggested by the links.

On azure i have the scope User.Read

Any advice?

2

Answers


  1. Initially, I registered Single-Tenant Microsoft Entra ID Application:

    enter image description here

    I got same error response for token validation after generation access token, When I ran the code which you mentioned by using scope: https://graph.microsoft.com/.default:

    enter image description here

    enter image description here

    Agree with @junnas, Scope which you provided for application, Need to request a token using scope defined by your application

    NOTE: Microsoft Graph API token is not meant to be validated, aud: https://graph.microsoft.com as it is not for the application validation, Is used for fetching Microsoft Graph API access

    To resolve the error, you need to avoid the scope of https://graph.microsoft.com/.defaultvalidating access token using Microsoft Graph API. You have to Exposed an API of your Application and validate the access token using your own application with Custom API.

    Added Application ID URI and I Expose an API like below:

    enter image description here

    Add and Grant Permission to your custom API like below:

    enter image description here

    After Exposing API, I generated client secret for application:

    enter image description here

    I modified script by changing the scope of accessing Microsoft Graph API to custom API.

    api://<application-id>/User.Read

    Use below Modified Script:

    
    client_id = "<client-id>"  
    tenant_id = "<tenant-id>"
    client_secret = "<client-secret>"
    username = "username"
    password = "password"
    scope = "api://<application-id>/User.Read"
    
    token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
    
    data = {
        "grant_type": "password",
        "client_id": client_id,
        "client_secret": client_secret,
        "scope": scope,
        "username": username,
        "password": password,
    }
    
    # Request
    response = requests.post(token_url, data=data)
    
    if response.status_code == 200:
        token_response = response.json()
        access_token = token_response.get("access_token")
        print("Access Token:", access_token)
    
        # UserInfo
        user_info_url = "https://graph.microsoft.com/v1.0/me"
        headers = {"Authorization": f"Bearer {access_token}"}
        user_response = requests.get(user_info_url, headers=headers)
    
        if user_response.status_code == 200:
            user_info = user_response.json()
            print("Informazioni utente:")
            print(user_info)
        else:
            print("User error:")
            print(user_response.status_code, user_response.text)
    else:
        print("Error")
        print(response.status_code, response.text)
    
    
    import msal
    import json
    
    # Configuration
    CLIENT_ID = "<client-id>"  
    CLIENT_SECRET = "<client-secret>"
    TENANT_ID = "<tenant-id>"
    RESOURCE = "api://<application-id>"
    
    # Token Verification Function
    def verify_token(access_token):
        try:
            # Initialize MSAL ConfidentialClientApplication
            app = msal.ConfidentialClientApplication(
                client_id=CLIENT_ID,
                client_credential=CLIENT_SECRET,
                authority=f"https://login.microsoftonline.com/{TENANT_ID}"
            )
    
            # Acquire a token on behalf of the user to validate the existing token
            result = app.acquire_token_on_behalf_of(
                user_assertion=access_token,
                scopes=[f"{RESOURCE}/.default"]
            )
    
            if "access_token" in result:
                print("Token is valid.")
                print("Token claims:", json.dumps(result.get("id_token_claims"), indent=2))
                return True
            else:
                print("Token validation failed:", result.get("error_description"))
                return False
    
        except Exception as e:
            print("An error occurred while verifying the token:", str(e))
            return False
    
    token_to_validate = input("Enter the token to validate: ")
    
    # Verify the token
    is_valid = verify_token(token_to_validate)
    if is_valid:
        print("The token is authentic.")
    else:
        print("The token is not authentic.")
    
    

    .

    Response:

    enter image description here

    Also, verified the token on https://jwt.io by decoding access token :

    enter image description here

    enter image description here

    If still issue persists, Create new application on App registration and try the same.

    Reference:

    SO Thread by Gilbert.

    SO Thread by me.

    Login or Signup to reply.
  2. The scope in the token generation is different form the scope you’re validating against. That’s most likely the issue.

    Check what @juunas commented.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search