How to diagnose Graph permission issues with Contact and Calendar resources - microsoft-graph-api

Having issues accessing graph resources for a specific user. Most have no issues. This specific user authenticates with our client via their school Outlook account which I am assuming is where the issue lies.
Our service attempts to create a specific folder using the /me/contactFolders endpoint. When we make the post, we get the error that the resource could not be discovered. Digging in a bit, I decided to login with their account to the Graph explorer and could not query endpoints such as, /me/contacts, /me/contactFolders, /me/events, etc.. None of the examples provided worked to fetch any data. I am assuming this has to do with permissioning of the users account, but I am not sure what permissions they would need to access both calendars and contacts (we are setting scopes and delegated permissions correctly as this problem is only associated with a couple users).
This is the error message that I received when trying to query graph:
{
"error": {
"code": "ResourceNotFound",
"message": "Resource could not be discovered.",
"innerError": {
"request-id": "5cfd7b28-a915-42cf-9bce-a8a2509c3f1f",
"date": "2018-12-20T18:48:34"
}
}
}
Any help in diagnosing this issue would be greatly appreciated!!

If you couldn't decode the token then you're most likely facing one of the following issues:
You obtained the token incorrectly
You're attempting to decode the Authorization Code rather than the Access Token (i.e. the string you get from 1st OAuth step rather than the 2nd).
The token is for Microsoft Account (a.k.a. MSA, lesser aka as an Xbox or Outlook.com account).
You can only decode tokens issued by Azure AD (AAD). School accounts (i.e. those ending in .edu) are basically the same as Work accounts, they're owned and managed by an Azure Active Directory.
In terms of checking which services are provisioned for the current User, you can obtain these from the /me endpoint so long as you have requested either the User.Read or User.ReadWrite scope. Note that this information isn't included by default so you'll need to specifically request the provisionedPlans. For example, the following query will return the current user's id, userPrincipalName, and their list of provisionedPlans (i.e. services):
https://graph.microsoft.com/v1.0/me/?$select=id,userPrincipalName,provisionedPlans
The results are pretty self-explanatory but in your particular case you're looking for a service named exchange (there are often more than one but they should all reflect the same status):
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users(id,userPrincipalName,provisionedPlans)/$entity",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038",
"userPrincipalName": "MeganB#M365x214355.onmicrosoft.com",
"provisionedPlans": [
{
"capabilityStatus": "Enabled",
"provisioningStatus": "Success",
"service": "exchange"
},

Related

Microsoft Graph People API returns a 404 despite consented permissions

When using the Microsoft Graph API endpoint /v1.0/me/people I'm presented with a 404 error despite consented with People.Read and People.Read.All permissions. I've added the response object and a screenshot of Graph Explorer below. Any suggestions on how to get a 200 OK instead? An empty array would be sufficient for me.
{
"error": {
"code": "ResourceNotFound",
"message": "Resource could not be discovered.",
"innerError": {
"date": "2021-04-24T07:09:23",
...
}
}
}
I'm experiencing this error on a Azure AD tenant I created for testing purposes with only two user objects and two groups. There are no Microsoft 365 services connected to this tenant. Judging by the People API documentation I can imagine this might have something to do with the 404 error, although I couldn't find it clearly specified that Microsoft 365 licenses are a requirement for the People API. It's good to note that other endpoints such as /v1.0/users and /v1.0/groups work.
Yes, To use the people API you need to have exchange license as all the people details are stored in Exchange.
You are able to get User and Group details because they are coming from Directory Services(Azure Active Directory) workload .

Microsoft Graph Mail Query - Getting "ErrorAccessDenied"

My company is using Microsoft 365 Business Standard licenses. We are using email through these accounts. We also have a few shared mailboxes. We are trying to create an app that uses the microsoft graph application permissions (rather than the delegated permissions) so the application can access one of the shared mailboxes without needing to be authenticated under the current user.
This is the steps we have taken so far:
Within Microsoft Azure, we have an application in which we have granted application api permissions for Mail.Read, and we have accepted Admin consent.
We authorized as an app, not as a user, in the application using this endpoint https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize, pointing out the required parameters for sending a request. Then, MS API builds this link:
https://login.microsoftonline.com/{some_string}/oauth2/v2.0/authorize?state={some_string}&scope=offline_access%20https%3A%2F%2Fgraph.microsoft.com%2F.default&response_type=code&approval_prompt=auto&redirect_uri=http%3A%2F%2Flocalhost&client_id={some_string}
When we follow the link, we get to the standard authorization form on the site. After we log in, a link is created, where we take the code and create the token: http://localhost/?code={some_string}&state={some_string}&session_state={some_string}
When we try to hit this endpoint: https://graph.microsoft.com/v1.0/users/sharedmailbox#domain.com/messages, we get this response:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"date": "2020-09-14T11:22:30",
"request-id": "{some_string}",
"client-request-id": "{some_string}"
}
}
}
I am thinking that hitting this endpoint https://graph.microsoft.com/v1.0/users/sharedmailbox#domain.com/messages requires us to pass the token previously generated and/or specify which application is making the query?
Any help or direction on what needs to be done to make this query work would be greatly appreciated. Thank you!
I am thinking that hitting this endpoint https://graph.microsoft.com/v1.0/users/sharedmailbox#domain.com/messages requires us to pass the token previously generated and/or specify which application is making the query?
Yes you would need to send the AccessToken in the Authorization header, you should also include the x-anchormailbox header which helps route the request to correct mailbox eg
GET https://graph.microsoft.com/v1.0/users/sharedmailbox#domain.com/messages HTTP/1.1
Host: graph.microsoft.com
Authorization: Bearer EwAoA8l6BAAU ... 7PqHGsykYj7A0XqHCjbKKgWSkcAg==
X-AnchorMailbox: sharedmailbox#domain.com
The other thing you might want to check is to ensure you have the correct scopes in your token you can use https://jwt.io/ for that
In order to use application permissions you will need to use the client credentials auth flow (not the authorization code auth flow which uses delegated permissions). To get a token make a request against "/oauth2/v2.0/token" and specify "grant_type=client_credentials" in the request. See examples of client credentials auth flow here for more details: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-client-creds-grant-flow

Microsoft Graph API - List Contacts for user users does not work?

I am attempting to use the "List Contacts" Microsoft Graph v1.0 API (https://learn.microsoft.com/en-us/graph/api/user-list-contacts?view=graph-rest-1.0) to retrieve the contacts of various users in my organization. In other words I want to list contacts in a delegated fashion.
My problem is that this API only seems to work for the user associated with the access token, e.g.:
Get Microsoft Graph API token for user "A"
Request to https://graph.microsoft.com/v1.0/users/USER_A_ID/contacts works fine
Request to https://graph.microsoft.com/v1.0/users/USER_B_ID/contacts fails
The error returned by the API is:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "[REQUEST_ID]",
"date": "[DATE]"
}
}
}
I have verified that the token contains the "Contacts.Read" scope by decoding the JWT token and examining the "scp" field, so I do not understand why the APIs saying that access is denied. Any ideas as to why this is failing?
Your need Contacts.Read.Shared or Contacts.ReadWrite.Shared, Your current Contacts.Read scope will only allow you to access the current users Contacts Folder. The other thing is the user requesting will still need to be granted the underlying delegate rights to the Target Mailbox Folder ( via Outlook delegation or Add-MailboxFolderPermission eg they need to be able to access the folder via Outlook or OWA).

Error when Posting or patching EducationClass with MSGraph

I'm trying to POST or PATCH an education class using Microsoft Graph but always get and error.
Request
https://graph.microsoft.com/V1.0/education/classes
{
"description": "Health Level 1",
"classCode": "Health 501",
"displayName": "Health 1",
"externalId": "11019",
"externalName": "Health Level 1",
"externalSource": "sis",
"mailNickname": "fineartschool.net"
}
Response
{
"code": "AccessDenied",
"message": "Required scp claim values are not provided.",
"innerError": {
"request-id": "e1183015-d942-491a-9949-4aa73bbef893",
"date": "2018-06-21T08:44:35"
}
}
My App has the needed permissions for creating an education class. (for testing, my app has all the application and delegated permissions possible). Posting users, groups etc is no problem.
More specific the needed permission:
After assigning the permission in the AD portal I did the following:
Get admin consent for the app https://login.microsoftonline.com/myTenant/adminconsent?client_id=myClientID&redirect_uri=MyRedirectURI
Get the authorization code https://login.microsoftonline.com/myTenant/oauth2/authorize?client_id=myClientID&response_type=code&redirect_uri=MyRedirectURI&response_mode=query&resource=https://graph.microsoft.com/
Get the access token
All with success.
After getting the Access Token I have the following scopes:
.....
EduRoster.Read
EduRoster.ReadBasic
EduRoster.ReadWrite
...
The Graph documentation says you need the permission Application EduRoster.ReadWrite.All
Also tested a POST and PATCH in Graph Explorer but get the same response.
This API requires "Application" rather than "Delegated" scopes. As you mentioned, it specifically requires the EduRoster.ReadWrite.All scope.
Which scopes get applied to a token depends entirely on which OAuth Grant you used to obtain the token:
Authorization Code Grant = Delegated
Implicit Grants = Delegated
Client Credentials Grant = Application
The reason you're not getting this scope in your Access Token is that you're using the Authorization Code grant (response_type=code) which will always result in Delegated scopes getting assigned.
In order to make this call, you'll need to obtain a token using the Client Credentials grant.
You might also find this article helpful (full disclosure, I am the author): Application vs Delegated Scopes.

Either scp or roles claim need to be present in the token

I'm trying to build an application that uses Microsoft Graph to automatically create and read pages in OneNotes stored in SharePoint 365.
I can successfully do this using Graph Explorer as long as I am logged in, but can't get it to work using a bearer token in Postman
The error I am getting is:
Either scp or roles claim need to be present in the token
I successfully get an access token using this:
https://login.microsoftonline.com/common/oauth2/v2.0/token
And passing in the grant_type, client_id, client_secret, code, redirect_uri and scope
Then I perform the following call, with the bearer token included in the header:
https://graph.microsoft.com/v1.0/sites
With the following getting returned:
{
"error": {
"code": "AccessDenied",
"message": "Either scp or roles claim need to be present in the token.",
"innerError": {
"request-id": "fa442c72-4ffe-493b-a33a-8e9e78c94f09",
"date": "2018-01-19T09:56:34"
}
}
}
I have set up graph permissions as per below. I have also tried enabling ALL Notes permissions configured with the same result though
Graph Permissions Image
One post I found said to check http://jwt.calebb.net/ what is returned in the token, and I found that it doesn't contain any roles, so I wonder if this is the problem.
You may need to state your tenant in the url when getting the token :
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
Thanks to Tsuyoshi Matsuzaki as seen here : How to use Application Permission with Azure AD v2
Your application can get access token using the following HTTP request
(OAuth). Note that you cannot use
https://login.microsoftonline.com/common/oauth2/v2.0/token (which is
commonly used) for getting the token. Instead, you must use
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token, which
identifies the specific tenant.
The call that you mentioned "https://graph.microsoft.com/v1.0/sites" is not valid.
Also request to ~/sites/... routes may need other permissions in addition to Notes.ReadWrite.
Recommend to follow steps mentioned in the following references:
https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_user
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service

Resources