azuremicrosoft-graph-apiaccess-tokenoutlook-calendar

403 Forbidden when trying to call Graph API to add calendar event


I have a working ASP.NET Core Web Application, which successfully can get a graphClient and call the graph API (for example can create OnLineMeeting) using C#

However if I try to create a Calendar event I got an exception

"Access is denied. Check credentials and try again."

(when debugging with Fiddler the response is 403 Forbidden accordingly)

What I've done so far:

What is suspicious for me, if I debug the request with fiddler, and decode the access token what _graphClient puts to the header, I do not see the Calendar.ReadWrite scope in the scopes...

{
    ...
    "scp": "Chat.Create Chat.Read Chat.ReadBasic Chat.ReadWrite email OnlineMeetingRecording.Read.All OnlineMeetings.Read OnlineMeetings.ReadWrite openid profile User.Read",
    ...
}

Question:

Why I got Access Denied? If the answer is the the missing scope, then how to add the Calendar Scopes? (to be honest I do not understand why those scopes in the scp claim, I did not specified those explicitly...)

Further diagnostics info:

API Permissions for the Application Registration:

API Permissions for the Application Registration

Code in the Program.cs, after that I can get graphClient using DI

builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
    .AddMicrosoftIdentityWebApp(builder.Configuration.GetSection("AzureAd"))
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddMicrosoftGraph(builder.Configuration.GetSection("GraphV1"))
    .AddInMemoryTokenCaches();

Solution

  • To create Calendar event, you need to grant admin consent to Calendars.ReadWrite delegated API permission:

    enter image description here

    Hence to resolve the error, make sure to grant admin consent to Calendars.ReadWrite permission

    Make sure the permission reflects in the access token scope like below:

    enter image description here

    For sample, I created calendar event successfully for the signed in user like below:

    POST https://graph.microsoft.com/v1.0/me/events
    Prefer: outlook.timezone="Pacific Standard Time"
    Content-type: application/json
    
    {
      "subject": "Let's go for lunch",
      "body": {
        "contentType": "HTML",
        "content": "Does noon work for you?"
      },
      "start": {
          "dateTime": "2024-05-15T12:00:00",
          "timeZone": "Pacific Standard Time"
      },
      "end": {
          "dateTime": "2024-05-15T14:00:00",
          "timeZone": "Pacific Standard Time"
      },
      "location":{
          "displayName":"Harry's Bar"
      },
      "attendees": [
        {
          "emailAddress": {
            "address":"xxx@contoso.com",
            "name": "User"
          },
          "type": "required"
        }
      ],
      "allowNewTimeProposals": true,
      "transactionId":"7E163156-7762-4BEB-A1C6-729EA81755A7"
    }
    

    enter image description here

    If you want to create calendar event for any other user, then grant Calendars.ReadWrite.All delegated API permission

    Note that: