Microsoft.Graph.Core create subscription "Access denied" - microsoft-graph-api

Following this walkthrough, I'm able to get a "subscription" on my Azure Function to a users mailbox.
However when I modify it to try to access a users onedrive, I'm able to access their files in the app, but when attempting to subscribe for a webhook I get the error below. I verified my token has Files.ReadWrite.All permission so I don't understand what I'm missing.
[2020-11-19T16:17:12.327Z] Executed 'SetDocSubscription' (Failed, Id=01410f60-0954-4e37-b9aa-2940cf9d0a17, Duration=2177ms)
[2020-11-19T16:17:12.330Z] System.Private.CoreLib: Exception while executing function: SetDocSubscription. Microsoft.Graph.Core: Code: ExtensionError
[2020-11-19T16:17:12.331Z] Message: Operation: Create; Exception: [Status Code: Forbidden; Reason: Access denied]
[2020-11-19T16:17:12.332Z] Inner error:
[2020-11-19T16:17:12.333Z] AdditionalData:
[2020-11-19T16:17:12.334Z] date: 2020-11-19T16:17:11
[2020-11-19T16:17:12.335Z] request-id: ccd648e7-b3fc-43f6-b1c5-481cbb5dcab6
[2020-11-19T16:17:12.336Z] client-request-id: ccd648e7-b3fc-43f6-b1c5-481cbb5dcab6
[2020-11-19T16:17:12.337Z] ClientRequestId: ccd648e7-b3fc-43f6-b1c5-481cbb5dcab6
...additional detail, calling function looks like this:
// Create a new subscription object
var subscription = new Subscription
{
ChangeType = "updated",
NotificationUrl = $"{notificationHost}/api/DocsNotify",
Resource = $"/users/{payload.UserId}/drive/root/",
ExpirationDateTime = DateTimeOffset.UtcNow.AddDays(2),
ClientState = Notify.ClientState
};
// POST /subscriptions
var createdSubscription = await graphClient.Subscriptions
.Request()
.AddAsync(subscription);
return new OkObjectResult(createdSubscription);

I am suspecting you're exceeding the limits here. When any limit (it can be Azure AD resource limitation as well) is
exceeded, attempts to create a subscription will result in an error
response - 403 Forbidden.
You can see the above error. In your
scenario, you will see the message property which will explain which
limit has been exceeded.
Here's the related doc.

Related

Invalid Request 409 when trying to subscribe to Microsoft Graph for Presence

Executing a subscription to presence request for users with the SDK targeting the MS Graph API is resulting in an error:
409Graph service exception Error code: InvalidRequest
Throwable detail: com.microsoft.graph.http.GraphServiceException: Error code: InvalidRequest
Error message: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
POST https://graph.microsoft.com/v1.0/subscriptions
SdkVersion : graph-java/v5.16.0
SdkVersion : graph-java/v5.16.0
[...]
400 : Bad Request
[...]
My code is:
final Subscription subscriptionRequest = new Subscription();
subscriptionRequest.changeType = ChangeType.UPDATED.toString();
subscriptionRequest.notificationUrl = notificationsHost;
subscriptionRequest.resource = "/communications/presences?$filter=id in ("+userIdsSb.toString()+")";
subscriptionRequest.clientState = subscribeToPresenceRequest.getClientState();
}el
subscriptionRequest.clientState = UUID.randomUUID().toString();
subscriptionRequest.expirationDateTime = OffsetDateTime.now().plusHours(1);
Subscription subscription = null;
try {
subscription = graphClient.subscriptions().buildRequest().post(subscriptionRequest);
response.setSubscribed(false);
failedIds.addAll(this.getFailedIds(e));
log.error("Error while trying to execute subscribeToPresence. ", e);
if(failedIds!=null && !failedIds.isEmpty()) {
log.error("The ids {} failed during the subscription request ",failedIds);
response.setFailedIds(failedIds);
}
}catch(Exception e) {
log.error("General Error while trying to execute subscribeToPresence. ", e);
retur
}
My subscription request includes the following values:
applicationId: null
changeType: UPDATED
clientState: 7fc6bf6b-6cc2-438d-a293-aa47539ad02a
creatorId: null
id: null
latestSupportedTlsVersion: null
lifecycleNotificationUrl: null
notificationQueryOptions: null
notificationUrl: https://myhost:port/graph/listen
notificationUrlAppId: null
oDataType: null
resource: /communications/presences?$filter=id in ('932b90ca-e5a4-42c7-a985-f4ddfc6d6715','6be2455d-63ac-4423-aa3e-7188fdbd5e73','41b3d168-5c28-4596-ba3b-d5c70a3c3967','8830a8bc-f882-4c13-b33a-7031423b5a24','ab548af7-d5a9-4388-9800-7668a20bb2b9')
expirationDateTime: 2023-02-02T16:41:11.737+02:00
includeResourceData: false
I saw this article regarding the beta version of the sdk https://learn.microsoft.com/en-us/graph/api/resources/subscription?view=graph-rest-1.0.
It indicates "Subscriptions to resources marked with an asterisk (*) are available on the /beta endpoint only." and presence is one of those resources. Is this related to my error?
I tried to use this version instead, but I still have the same Invalid request error.
I am using delegated permission to call the /subscription/presence endpoint of the Microsoft Graph API.
I was able to fetch previous subscriptions by calling /subscription endpoint and was also able to find users through /users/filter endpoint with application permission.
Is there something wrong in the format of my subscription request? This all worked fine a few months ago and I haven't changed anything.
Is this related to SSL/TLS secure communication? But then again, why would my other requests get responses?

Register GraphAPI subscription in multi tenant case

Having an Azure "App registration" which is single tenant it is possible to register a subscription for the graphAPI for calendar events with the following resource:
/users/<user-id>/events
However after switching the app registration to multi-tenancy when attempting to register by calling /users/<user-id>/events if fails with the error:
Error: Operation: Create; Exception: [Status Code: NotFound; Reason: The requested user '<user-id>#72f988bf-86f1-41af-91ab-2d7cd011db47' is invalid.]
The GUID 72f988bf-86f1-41af-91ab-2d7cd011db47 apparently seems to be the TenantId of Microsoft according to this reference.
So what probably should be different is that I have to "tell" which tenant the user belongs to when registering the subscription in the case of a multi-tenant app registration. What I tried so far without success is the following: /users/<user-id>#<tenant-id>/events. The error message then is:
Status Code: NotFound; Reason: The requested user '<user-id>#<tenant-id>' is invalid.]
So the question is: How must I pass the tenant-id in the request so the correct user can be resolved?
Update
The error observed happens using the msal-client (#azure/msal-node) like this to obtain the graphAPI access token:
// Get a token using client credentials
const response =
await msalClient.acquireTokenByClientCredential({
scopes: ['https://graph.microsoft.com/.default']
});
// First param to callback is the error,
// Set to null in success case
done(null, response.accessToken)
Where the msalClient is instantiated like this:
const clientConfig: any = {
auth: {
clientId: clientId,
authority: authority,
clientSecret: configuration.getSyncServerClientSecret()
}
};
msalClient = new msal.ConfidentialClientApplication(
clientConfig
);
But requesting a token manually with Postman and then calling https://graph.microsoft.com/v1.0/subscriptions just works....
So the error must be with the usage of msalClient.

How to create subscription for specific event of Graph API

I want to get notifications on a specific event that I have created from my application. For that, I am using the below code to subscribe to a specific event.
var subscription = new Subscription
{
ChangeType = "updated,deleted",
NotificationUrl = $"{_notificationHost}/listen",
Resource = "me/events/{event-id}",
ClientState = Guid.NewGuid().ToString(),
IncludeResourceData = false,
// Subscription only lasts for one hour
ExpirationDateTime = DateTimeOffset.UtcNow.AddHours(1)
};
But while creating it throws an exception:
Error creating subscription: Code: ExtensionError Message: Operation:
Create; Exception: [Status Code: BadRequest; Reason: The value
'https://outlook.office365.com/api/beta/Users('{userid}')/Events('{event-id}')'
of parameter 'Resource' is not supported.]
Just ran into this same issue. It looks like the Subscription API doesn't support subscriptions on specific events, only the entire calendar. There's an example for subscriptions to events in the "Resources examples" section, which looks like exactly what you want: me/events. The ID of the updated/deleted event is included in the callback, so if you only care about certain events, you can use that.

ErrorInternalServerError Getting mine content

I am trying to get content (MIME) of an email via Microsoft Graph Api:
var mime = await _graphClient.Users [user] .Messages [mailid] .Content.Request (). GetAsync ();
for some users I'm get this error:
enter image description here
Code: ErrorInternalServerError
Message: An internal server error occurred. The operation failed.
ClientRequestId: bd559710-a820-4c37-b386-fea7a72f3eec

Microsoft graph API return ExtensionError when creating subscription

I have an application that uses MS Graph API to subscribe to calendar events. For most of the users this works fine, however, for certain users https://graph.microsoft.com/v1.0/subscriptions always fail with ExtensionError.
For the same user manually triggered sync works fine.
Other thread here say the issue got fixed for them over time but I am facing this issue for a long time now.
Example error:
Error message: Operation: Create; Exception: [Status Code: NotFound; Reason: The requested user '<user#email.com>' is invalid.]
POST https://graph.microsoft.com/v1.0/subscriptions
Prefer : IdType=ImmutableId
SdkVersion : graph-java/v2.3.2
SdkVersion : graph-java/v2.3.2
Authorization : [PII_REDACTED]
{"changeType":"created,updated,deleted","clientSta[...]
404 : Not Found
[...]

Resources