Token generated misses SCP

Bani, Dario CFA 20 Reputation points
2023-07-25T15:09:48.97+00:00

Hi experts,

I've registered an APP on Azure and obtained a "client_id", a "tenant_id" and a "client_secret". Then I added to the "API Permissions" all the "Delegated" accesses to "Mail" and "Chat" since I want to API to interact with Outlook and Teams.
I'm using this code in Python to get the token.

from datetime import datetime
import requests
import msal

# Initialize the information for the API
client_id = "XXXX"
client_secret = "XXXX"
tenant_id = "XXXX"
authority = "https://login.microsoftonline.com/" + tenant_id
scope = ["https://outlook.office365.com/.default"]
user_principal_name = "XXXX.XXXX@XXXX.com"

# Create a confidential client application
app = msal.ConfidentialClientApplication(
    client_id=client_id,
    authority=authority,
    client_credential=client_secret,
)

# Get a token for the app
result = app.acquire_token_for_client(scopes=scope)
result['access_token']

I'm able to generate a token but it doesn't contain the "scopes" I've added in the API Permissions.
My understanding is that "Scp" are required. Currently when trying to access the emails subject with this code:

if "access_token" in result:
    # Define the endpoint URL
    url = f"https://graph.microsoft.com/v1.0/users/{user_principal_name}/mailFolders/inbox/messages"

    # Set up query parameters
    today = datetime.now().isoformat(timespec='seconds')
    subject_to_find = "test"
    query_parameters = {
        "$filter": f"receivedDateTime ge {today}Z and subject eq '{subject_to_find}'",
        "$select": "subject",
    }

    # Set the headers
    headers = {
        'Authorization': 'Bearer ' + result['access_token'],
        'Content-Type': 'application/json'
    }

    print(f"Headers: {headers}")
    print(f"Query Parameters: {query_parameters}")

    # Make the API request
    response = requests.get(url, headers=headers, params=query_parameters)

    # Check if the desired subject was found
    if response.status_code == 200:
        data = response.json()

        if len(data["value"]) > 0:
            print(True)
        else:
            print(False)
    else:
        print(f"API call failed with status code {response.status_code}. Response content: {response.content}")
else:
    print(f"Could not acquire token: {result}")

But I got this error

API call failed with status code 401. Response content: b'{"error":{"code":"InvalidAuthenticationToken","message":"Access token validation failure. Invalid audience.","innerError":{"date":"2023-07-25T14:37:48","request-id":"6fc0cb65-694c-4fe4-9e18-fa36f2aca8e8","client-request-id":"6fc0cb65-694c-4fe4-9e18-fa36f2aca8e8"}}}'

Could you please let me know what I'm doing wrong and why the token doesn't reflect the access I granted to the API in the scopes?

Regards,
Dario

Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
9,936 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
18,616 questions
0 comments No comments
{count} votes

Accepted answer
  1. Vasil Michev 90,876 Reputation points MVP
    2023-07-25T15:28:18.1066667+00:00

    You're mixing things a bit here. There are two types of permissions any given app can use: application permissions and delegate permissions. According to the description above, you have added some delegate permissions to your app. Those permissions however require the application to run in a user context, i.e. you need to use any of the user-centric auth flows. In your example, you are authenticating with a client secret instead - this is corresponding to the other scenario, application permissions.

    TL;DR - If you want to leverage the client credentials flow (auth via client secret), make sure you add Application permissions instead of Delegate ones. If you do want to leverage the Delegate permissions you've added, authenticate as a user (for example by leveraging the auth code flow).

    0 comments No comments

0 additional answers

Sort by: Most helpful