Invalid Request 409 when trying to subscribe to Microsoft Graph for Presence - microsoft-graph-api

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?

Related

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.

Getting presence data from the Microsoft Graph API

I have been following the instructions to setup the Microsoft Graph Webhooks Sample for Node.js app here: https://github.com/microsoftgraph/nodejs-webhooks-rest-sample
However, when it tries to create the subscription I receive the following error:
Error: Operation: Create; Exception: [Status Code: BadRequest; Reason: Unsupported workload.]
at new GraphError (C:\Dev\nodejs-webhooks-rest-sample\node_modules\#microsoft\microsoft-graph-client\src\GraphError.ts:59:3)
at Function.GraphErrorHandler.constructErrorFromResponse (C:\Dev\nodejs-webhooks-rest-sample\node_modules\#microsoft\microsoft-graph-client\src\GraphErrorHandler.ts:62:18)
at Function.<anonymous> (C:\Dev\nodejs-webhooks-rest-sample\node_modules\#microsoft\microsoft-graph-client\src\GraphErrorHandler.ts:89:31)
at step (C:\Dev\nodejs-webhooks-rest-sample\node_modules\tslib\tslib.js:141:27)
at Object.next (C:\Dev\nodejs-webhooks-rest-sample\node_modules\tslib\tslib.js:122:57)
at C:\Dev\nodejs-webhooks-rest-sample\node_modules\tslib\tslib.js:115:75
at new Promise (<anonymous>)
at Object.__awaiter (C:\Dev\nodejs-webhooks-rest-sample\node_modules\tslib\tslib.js:111:16)
at Function.GraphErrorHandler.getError (C:\Dev\nodejs-webhooks-rest-sample\node_modules\#microsoft\microsoft-graph-client\lib\src\GraphErrorHandler.js:88:24)
at GraphRequest.<anonymous> (C:\Dev\nodejs-webhooks-rest-sample\node_modules\#microsoft\microsoft-graph-client\src\GraphRequest.ts:386:55)
My subscription configuration is as follows:
exports.subscriptionConfiguration = {
changeType: 'updated',
notificationUrl: 'https://123456789.ngrok.io/listen',
resource: '/me/presence',
clientState: 'SecretClientState',
includeResourceData: false
};
and I have the following permissions associated with my Azure app:
Azure app permissions
Can anyone suggest what I am doing wrong?
I tried the following which worked for me. Sharing the related info:
This API (me/presence) uses the Presence.Read.All delegated permission - i see that you already specified it.
A signed-in user is required.
Follow these steps to set up a webhook and retrieve these notifications:
Subscribe to a single user’s presence through the /communications/presences/{id} path.
Subscribe to a maximum number of 650 users by using /communications/presences?$filter=id in ({id},{id}...).
The {id} represents a user ID GUID.
Subscriptions expire every hour and must be renewed.

Microsoft.Graph.Core create subscription "Access denied"

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.

Twilio Invalid Access Token Signature (iOS - Swift)

I am using Twilio's latest SDK they released on CocoaPods as of today. I am trying to implement VOIP feature to my app with Twilio Programmable Voice. My backend is .net which also uses the latest release of Twilio Helper Library for C#.
My client code looks like:
fetchAccessToken { (accessToken: String) in
TwilioVoice.register(withAccessToken: accessToken, deviceToken: deviceToken) { (error) in
if let error = error {
NSLog("An error occurred while registering: \(error.localizedDescription)")
}
else {
NSLog("Successfully registered for VoIP push notifications.")
}
}
}
What I get in the console is as following:
voipTestWithTwilio[2431:517236] [ERROR TwilioVoice] Inside register:deviceToken:completion:, failed to register for Twilio push notifications. Error:Invalid access token signature
voipTestWithTwilio[2431:517236] An error occurred while registering: Invalid access token signature
This is the C# code that actually creates the token:
var grant = new VoiceGrant
{
OutgoingApplicationSid = outgoingApplicationSid
};
var grants = new HashSet<IGrant> { { grant } };
var token = new Token(
accountSid: accountSid,
signingKeySid: apiKey,
secret: apiSecret,
identity: identity,
grants: grants
);
return token.ToJwt();
I have been looking for the issue on the internet, nothing helped so far. I have tried contacting them but have not got any response back. I also tried creating new api keys and even a new project for a couple times on Twilio. Can anybody say something about the issue?
UPDATE
I added push notification sid to VoiceGrant and now I’m getting 403 Forbidden.
On Twilio error codes page it is explained as: “The expiration time provided in the Access Token exceeds the maximum duration allowed.” which is definitely not my case. However, I tried passing expiration parameter in Token constructor with various values which didn’t change the result.
The problem is still persisting.
I solved the issue. It was because my server returned the token with quotation mark.
I remember print(token)'ing on client (iOS) to see whether there is encoding issue or something and all I see was a proper token between quotation marks. Since token is a string value, I didn't pay attention to quotation part of it. That's where I was wrong.

AWS SNS Error Invalid parameter: Token Reason: Endpoint xxx already exists with the same Token, but different attributes

Using AWS SDK for iOS v2.0.8
Quick question:
How do I [snsClient deleteEndpoint:request], when I do not know this endpoint's arn? I do have the deviceToken.
Detail:
I am receiving the error Token Reason: Endpoint arn:aws:sns:...c6 already exists with the same Token, but different attributes when I attempt to create an endpoint for my iPhone:
// Async call to create the platform endpoint
[[[_awsSnsClient createPlatformEndpoint:request] continueWithSuccessBlock:^id(BFTask *task) {
// success
_awsPlatformEndpoint = task.result; // Save off the endpoint data
[self awsUsubscribeAllSubscriptions];
return nil;
}] continueWithBlock:^id(BFTask *task) {
if (task.error) {
// failed with error
ALog(#"Error: Code:%li localizedDesc:%# Exception:%#", (long)task.error.code, task.error.localizedDescription, task.exception);
if(task.error.code == 7) {
// delete offending endpoint and create it again?
}
}
return nil;
}];
When I create the endpoint I do not set the attributes, I do set customUserData based on client data which can change. In the SDK docs for customUserData it says: Arbitrary user data to associate with the endpoint. Amazon SNS does not use this data. The data must be in UTF-8 format and less than 2KB.
When I delete the endpoint from the SNS console, I can get a new endpoint. So how do I deleteEndpoint, when I do not know this endpoint's arn? I can see the arn in the AWS logging, but not in the BFTask* error object.
I've seen the ruby solution at 19551067, but I do not see a way the read the message, the ruby example reads the message from the exception, task.exception == nil in my case. I received from AWS verbose logging:
Using AWS logging:
2014-10-01 06:48:54.489 myApp[1665:1345740] AWSiOSSDKv2 [Verbose] AWSURLResponseSerialization.m line:244 | -[AWSXMLResponseSerializer responseObjectForResponse:originalRequest:currentRequest:data:error:] | Response body: [<ErrorResponse xmlns="http://sns.amazonaws.com/doc/2010-03-31/">
<Error>
<Type>Sender</Type>
<Code>InvalidParameter</Code>
<Message>Invalid parameter: Token Reason: Endpoint arn:aws:sns:us-west-2:245211809793:endpoint/APNS_SANDBOX/myApp-Dev/7bxxx-xxxx-xxxx-xxxc6 already exists with the same Token, but different attributes.</Message>
</Error>
<RequestId>d874ac10-e6de-5a4d-805e-e0b6ee58e5b7</RequestId>
</ErrorResponse>
]
What I can get from (BFTask* task).error:
2014-10-01 06:48:54.494 myApp[1665:1345740] __46-[AppDelegate_Shared awsStartWithDeviceToken:]_block_invoke1279 [Line 3558] Error:
Code:7
localizedDesc:The operation couldn’t be completed. (com.amazonaws.AWSSNSErrorDomain error 7.)
Exception:(null)
** Update 2014-10-01 **
My development iPad started doing this just after updating to iOS 8.0.2. I do add the version number into the customUserData - but Amazon SNS does not use this field... right?
** Update 2014-01-01 19:06 GMT-07:00 **
Added task.error.userInfo to the error block. I'll parse the message and delete the endpoint when this comes up. An option in AWSSNSCreatePlatformEndpointInput to override this error, update the endpoint and return the endpoint would be nice ;)
thank you!
Console now has:
2014-10-01 18:58:50.836 iFlightBag[1862:1493821] __46-[AppDelegate_Shared awsStartWithDeviceToken:]_block_invoke1281 [Line 3559] Error:
Code:7
localDesc:The operation couldn’t be completed. (com.amazonaws.AWSSNSErrorDomain error 7.)
Exception:(null)
userInfo:{
Code = InvalidParameter;
Message = "Invalid parameter: Token Reason: Endpoint arn:aws:sns:us-west-2:245211809793:endpoint/APNS_SANDBOX/LevelFlightMobile-Dev/7b70d2c4-846e-3afd-a1ba-eedaa00f7ac6 already exists with the same Token, but different attributes.";
Type = Sender;
"__text" = (
"\n ",
"\n ",
"\n ",
"\n "
);
}
The userInfo property of task.error should contains a dictionary representation of the error XML.

Resources