Search code examples
azureazure-active-directorycalendarmicrosoft-graph-apimicrosoft-graph-mail

Permission issues while trying to get Outlook Calendar events using Microsoft Graph API - Access is denied. Check credentials and try again


Getting the below error while trying to access the user's Calendar events data through Microsoft Graph API:


{'error': {'code': 'ErrorAccessDenied', 'message': 'Access is denied. Check credentials and try again.'}}

Registered a new Azure AD application and granted the required permission.

Azure AD Calendar permissions

Permission Type: Application
Granted Permissions: Calendars.Read, Calendars.ReadWrite, User.ReadAll
Authentication: Client Credential flow
Admin Consent: Granted

Requested Endpoints:

  • Get Calendars
  • List Calendars
  • List Events
  • Get Schedule
  • Get CalendarView

Expected Output:

Similar to mentioned here for a given user: ( https://learn.microsoft.com/en-us/graph/api/calendar-list-events?view=graph-rest-1.0&tabs=http#response-2 )

Actual Output:


{'error': {'code': 'ErrorAccessDenied',           
'message': 'Access is denied. Check credentials and try again.'}}

Generated Access token roles (jwt.ms):

Access token roles

More details:

  1. Access token generated successfully with correct scopes
  2. Able to read user information with this access token
  3. Only Calendar related requests are failing with access denied error
  4. Using Microsoft Authentication Library(MSAL) for generating token
  5. Using Python requests library to generate graph API calls

Sample Code:

import msal
import json
import requests
from pprint import pprint


tenant_id = "azure-tenant-id"
client_id = "application-id"
client_secret = "application-secret"


app = msal.ConfidentialClientApplication(
    client_id         = client_id,
    client_credential = client_secret,
    authority         = f"https://login.microsoftonline.com/{tenant_id}")

scopes = ["https://graph.microsoft.com/.default"]

# Obtain bearer token from MS Graph
token = None
token = app.acquire_token_for_client(scopes = scopes)

# print(f"Access Token: {token['access_token']}")

# The App Registration's object ID
userPrincipalName = "[email protected]"  

req_uri = f"https://graph.microsoft.com/v1.0/users/{userPrincipalName}/events"
# req_uri = "https://graph.microsoft.com/v1.0/users?$select=displayName,mail,id"
# req_uri = f"https://graph.microsoft.com/v1.0/users/{user_id}/calendar/getSchedule"
# req_uri = f"https://graph.microsoft.com/v1.0/users/{userPrincipalName}/calendarView?startDateTime=2020-01-01T19:00:00-08:00&endDateTime=2020-01-02T19:00:00-08:00"

req_headers = {
    "Authorization": "Bearer " + token['access_token'],
    "Content-Type": "application/json"
}

req_body = json.dumps(
    {        
        "schedules": ["user@domaincom"],
        "startTime": {
            "dateTime": "2023-01-01T00:00:00",
            "timeZone": "Pacific Standard Time"
        },
        "endTime": {
            "dateTime": "2023-02-15T00:00:00",
            "timeZone": "Pacific Standard Time"
        },
        "availabilityViewInterval": 60
    }
)

# result = requests.post(url = req_uri, headers = req_headers, data = req_body)
result = requests.get(url = req_uri, headers = req_headers)

pprint(json.loads(result.content))

Solutions already tried:

  • Revoked all permissions from this application and granted them again as mentioned on this Microsoft QA page - not working
  • Registered new application with the required permissions - not working
  • For my account able to get data - tested from Graph API explorer - so the O365 subscription is part of the same tenant.

I am not sure what exactly is missing here. Any help would be appreciated.


Solution

  • The issue was fixed (details here) with help from Microsoft Support.

    Solution:

    • Remove Calendars.ReadBasic.All permission from the Application
    • Revoke Admin consent granted to this permission

    Updated Permission:

    Outlook Calendar Read Permission