Python code using MSAL is failing to recognise my free Outlook email account

Grant Rule 20 Reputation points
2024-07-11T08:09:57.2333333+00:00

I'm using Python code with MSAL to read emails from my free Outlook account. I have set up Apps in Azure and correctly added permissions and granted admin access, etc. When I use the App that has delegated permissions using app.acquire_token_for_client it works as expected. However, when I use the App with application permissions using ConfidentialClientApplication, authentication fails. What could be the problem? Is it because I am using free Outlook and Azure accounts. All my research on-line indicates it should be possible.

The App permissions are as follows

User's image

My Python code is below. When I run it I get:

Access token acquired successfully.

Failed to retrieve emails.

Status Code: 404

Response: {'error': {'code': 'ErrorInvalidUser', 'message': "The requested user '####@hotmail.com' is invalid."}}

from msal import ConfidentialClientApplication

import requests

# Replace with your own email address
user_email = "####@hotmail.com"

client_id = '#####################################'
client_secret = '###############################'
tenant_id = '###################################'

authority = f"https://login.microsoftonline.com/{tenant_id}"

# Acquire the access token
app = ConfidentialClientApplication(
    client_id,
    authority=authority,
    client_credential=client_secret
)

scope = ["https://graph.microsoft.com/.default"]
result = app.acquire_token_for_client(scopes=scope)

if "access_token" in result:
    access_token = result["access_token"]
    print("Access token acquired successfully.")
else:
    print("Failed to acquire token.")
    print(result.get("error"))
    print(result.get("error_description"))
    print(result.get("correlation_id"))  # You might need this when reporting a bug
    exit()

# Make a request to the Microsoft Graph API to get the user's emails
headers = {
    'Authorization': f'Bearer {access_token}',
    'Content-Type': 'application/json'
}

# Correct the endpoint URL by using /users/{user_email}/mailFolders/inbox/messages
endpoint = f'https://graph.microsoft.com/v1.0/users/{user_email}/mailFolders/inbox/messages'

response = requests.get(endpoint, headers=headers)

if response.status_code == 200:
    emails = response.json().get('value', [])
    print(f"Found {len(emails)} emails in the inbox.")
    for email in emails:
        print(f"Subject: {email['subject']}")
        print(f"From: {email['from']['emailAddress']['address']}")
        print(f"Received: {email['receivedDateTime']}")
        print("----")
else:
    print("Failed to retrieve emails.")
    print(f"Status Code: {response.status_code}")
    print(f"Response: {response.json()}")
Outlook
Outlook
A family of Microsoft email and calendar products.
3,403 questions
Microsoft Graph
Microsoft Graph
A Microsoft programmability model that exposes REST APIs and client libraries to access data on Microsoft 365 services.
11,387 questions
Microsoft Entra ID
Microsoft Entra ID
A Microsoft Entra identity service that provides identity management and access control capabilities. Replaces Azure Active Directory.
20,554 questions
{count} votes

Accepted answer
  1. CarlZhao-MSFT 40,141 Reputation points
    2024-07-12T06:49:03.5866667+00:00

    Hi @Grant Rule

    You cannot use application permissions to retrieve emails for personal or guest users because these users do not have mailboxes available in your tenant, their mailboxes exist in their home tenant. Therefore, you can only log these users into your multi-tenant application and call the /me/mailFolders/inbox/messages endpoint to retrieve emails in their home tenant.

    Hope this helps.

    If the reply is helpful, please click Accept Answer and kindly upvote it. If you have additional questions about this answer, please click Comment.


0 additional answers

Sort by: Most helpful