I’m working on a web app (SPA and backend) that must constantly access the user’s Outlook calendar. The users may come from multiple directories and personal accounts. The app will work 24/7, running the background service and modifying the user’s calendar without the user’s involvement. So far, I have completed the following:
-
I created AAD app registration with supported account types "Accounts in any organizational directory (Any Microsoft Entra ID tenant – Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)."
-
I set RedirectURI to be my SPA base URL and created a secret.
-
I implemented authentication in SPA with MSAL (msal-browser). My authorization request looks like this: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?scope=https://graph.microsoft.com/Calendars.ReadWrite+openid+profile+offline_access&response_type=code&client_id=my_client_id...
-
After the user successfully authenticates and gives all permissions, his account looks like
-
I also retrieved tenantId from the id token (tid claim)
-
Just to verify that my access_token is valid and permissions set correctly, I successfully requested events from https://graph.microsoft.com/v1.0/me/events At this point, I assume the user has successfully given all the required permissions to my app and my background service can access the user’s calendar
-
I successfully requested access_token with client_credentials flow
curl –location ‘https://login.microsoftonline.com/tenantId_from_step_5/oauth2/v2.0/token’
–header ‘Content-Type: application/x-www-form-urlencoded’
–data-urlencode ‘client_id=clientId_from_step1‘
–data-urlencode ‘scope=https://graph.microsoft.com/.default’
–data-urlencode ‘client_secret=secret_from_step2‘
–data-urlencode ‘grant_type=client_credentials’
I requested user’s events with the access_token obtained on the previous step https://graph.microsoft.com/v1.0/users/[email protected]/events but got the following error
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again."
}
}
I’m stuck at this point and would appreciate any help or suggestions.
UPDATE:
JWT Token obtained with credential_flow (step 7 from above) from https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/oauth2/v2.0/token misses roles (permissions)
I think all personal accounts share the same tenantId=9188040d-6c67-4c5b-b112-36a304b66dad
2
Answers
Try removing the admin consent requirement.
I created a Microsoft Entra multi-tenant application and granted API permission like below:
Generated access token via Client credential flow:
By using the above access token, I tried to call events API for personal account and got the same error:
Hence to resolve the error, make use of Authorization code flow:
Grant delegated API permissions:
Generate auth code:
And sign-in with personal account:
Generated access token Authorization code flow:
I am able to successfully call events API:
To do the same JavaScript, refer this MsDoc Acquire a token to call a web API (single-page apps) – Microsoft identity platform | Microsoft
Reference:
Exceptions in MSAL Java – Microsoft Authentication Library for Java | Microsoft