Reputation: 67
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
My app (outlook-sync-dev) permissions in Azure Portal:
Upvotes: 1
Views: 405
Reputation: 67
I think that @Rukmini's answer is correct, but omits some not-obvious details. I wanted to add clarification in the comment, but it is just too long, so I'm adding the answer.
My initial question was about accessing Outlook Calendar (of a personal account) via Graph API from the background service. What we know so far:
Therefore, the proposed solution is the following:
Upvotes: 0
Reputation: 15829
I created a Microsoft Entra multi-tenant application and granted API permission like below:
Generated access token via Client credential flow:
https://login.microsoftonline.com/9188040d-6c67-4c5b-b112-36a304b66dad/oauth2/v2.0/token
client_id:ClientID
client_secret:ClientSecret
scope↵:https://graph.microsoft.com/.default
grant_type:client_credentials
By using the above access token, I tried to call events API for personal account and got the same error:
https://graph.microsoft.com/v1.0/users/UserID/events
Note that: Client credential flow does not support Microsoft personal accounts. Hence you must make use of any user interaction flow to call personal account related APIs that is the user must perform login process.
Hence to resolve the error, make use of Authorization code flow:
Grant delegated API permissions:
Generate auth code:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
&client_id=ClientID
&response_type=code
&redirect_uri=https://jwt.ms
&response_mode=query
&scope=https://graph.microsoft.com/.default offline_access
&state=12345
And sign-in with personal account:
Generated access token Authorization code flow:
https://login.microsoftonline.com/common/oauth2/v2.0/token
grant_type:authorization_code
client_id:ClientID
client_secret:ClientSecret
scope:https://graph.microsoft.com/.default offline_access
code:Code
redirect_uri:https://jwt.ms
I am able to successfully call events API:
https://graph.microsoft.com/v1.0/users/UserID/events
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
Upvotes: 0