Microsoft Graph 'created' subscription is not working with application token - azure

I have a working application integrated with Microsoft Graph with application token received with a certificate.
I can subscribe to "updated,deleted" events on user contacts and calendars but I can't subscribe to "updated,deleted,created".
Resource used /users/<email>/contacts and /users/<email>/calendars
It gives me the following error on POST /subscriptions :
error": {
"code": "ExtensionError",
"message": "Operation: Create; Exception: [Status Code: NotFound; Reason: Not Found]",
"innerError": {
"request-id": "<skip>",
"date": "<skip>"
}
I just checked with a sandbox and it works with a user authenticated (I haven't check fully but at least it timeouts on a server side). Though with application token it's not working.

As per the documentation: 'User and group notifications support updated and deleted changeType.'
Reference:
https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/resources/subscription

Drive root item notifications support only the updated changeType. User and group notifications support updated and deleted changeType.

I think I made something wrong in the beginning.
/users/<email>/calendars is a wrong link. To get user events it should be /users/<email>/calendar/events.
And /users/<email>/contacts created is working properly.

Related

Check if users deleted in clients Azure AD

I am integrating Login with Azure AD for one of my clients on my website. I am only targeting one specific group in their organisation, and not everybody in the entire organisation.
This new feature has 2 requirements:
We need to create an account for people logging in via their email using our clients Azure AD.
We need to run a CRON job daily to check if anybody has been removed in their AD (due to them leaving the company), so we also need to remove their profile in our application.
For number 1, I think it's sufficient to call the /authorization, /token and /userinfo endpoints. Is this correct?
But for number 2, I am having issues to see how this is possible.
When browsing the graph explorer (https://developer.microsoft.com/en-us/graph/graph-explorer) I can find the following 2 API methods:
GET all users in the organization /users ---> But i am unsure whether this returns all the users in their AD, or only the ones applicable for my application?
GET direct members of a group with count /groups/<id</members ---> Is this the one I am looking for when they are assigned into a specific group?
I've also found this SO link : https://stackoverflow.com/a/64553305 which talks about saving the access token and refresh token. Is it possible if I save these two to fetch the userinfo at any point in time? This way I could possibly query all the created accounts each day and if one of them returns a status deleted, or empty I know the account no longer exists? Or is this not an option?
Thanks in advance!
UPDATE:
I noticed that my client granted me the User.Read and User.Read.All graph permissions.
But i'm not certain how to call this API? When calling this API in Postman :
https://graph.microsoft.com/v1.0/users/123-this-is-the-id
I am getting the following response:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"date": "2021-10-07T12:59:05",
"request-id": "...",
"client-request-id": "..."
}
}
}

Issue Getting User Chats - Graph API

I am trying to get signed in user's chat messages in a B2C Tenant. I am getting 401 Unauthorized error. Tried the same with graph explorer which is also giving same error. I am using https://graph.microsoft.com/beta/me/chats endpoint. As per MSDN documentation, I have already given permissions to my Azure app. When I am trying this with a non B2C tenant, the API call succeeds.
Please help me with this issue. Error I am seeing is given below.
{
"error": {
"code": "Unauthorized",
"message": "Unauthorized",
"innerError": {
"date": "2021-06-24T15:30:29",
"request-id": "f2804d78-59d2-4917-ae2e-cb73b3eb0872",
"client-request-id": "52452dfc-cae9-d409-92b9-9e9586cab6c3"
}
}
}
With some research I found out that B2C tenants don't allow Teams at the first place. I have switched to a B2B tenant and it started working like a charm.

'Unauthorized' error when requesting '/joinedTeams' from Microsoft Graph

I am setting up an app for modifying a Microsoft Teams account (teams/channels) through the Microsoft Graph API, but I can't get responses from all of the endpoints which I need to call.
I have followed the guide for creating an app with application permissions and acquired access (and refresh) token(s) succesfully.
Calling the https://graph.microsoft.com/v1.0/users/<user guid>/joinedTeams endpoint yields a response as follows:
{
"error": {
"code": "Unauthorized",
"message": "Unauthorized",
"innerError": {
"date": "2020-06-24T12:37:53",
"request-id": <guid>
}
}
}
while calling endpoints such as https://graph.microsoft.com/v1.0/users works as described. It would seem that the app hasn't gotten consent and/or permissions to access these, but after signup they are listed on the API permissions in the azure portal enterprise applications page, and the access token JWT contains the specified permissions as a roles object.
From the JWT:
"roles": [
"TeamSettings.ReadWrite.All",
"User.ReadWrite.All",
"Directory.ReadWrite.All",
"Group.ReadWrite.All",
"TeamMember.ReadWrite.All",
"Team.ReadBasic.All",
"GroupMember.ReadWrite.All",
"Member.Read.Hidden"
]
I have tried with the Directory.ReadWrite.All permission and also with the full permission list listed on the permissions page for the /joinedTeams endpoint and they all elicit the same error.
Curiously, according to this a 401 - Unauthorized response would be given for expired (or similarly invalid) tokens, however that seems to clearly not be the case as I can call other endpoints with that very token.
What am I missing?
Solved thanks to #MikeOliver
When I signed up for Teams it created another directory. Only that second directory had a Teams "license" (visible from the azure portal's License page).

calling microsoft graph api via another rest service

Good day!
We need a calendar facility for the project that we're working in right now. For some reason, we are limited to using the Office 365 calendar or the outlook calendar. We stumbled upon the Microsoft Graph APIs which seems to be the right tool to fulfill what we want to do. So the idea is to create a Microsoft account which will be used as the main calendar where our wrapper(wrap the microsoft graph API calls) API can pull events from and eventually disseminate to client requests.
So here is what we've done so far:
Created a Microsoft account with the domain of #outlook.com
Plotted some calendar events using the said Microsoft account
Tried to follow this guide from the Microsoft site.
We agreed to create a wrapper API which will call the Microsoft Graph APIs but before this we tried to access the said APIs via postman. The problem is that postman cannot get any response from the endpoint of the /authorize API which is need to gain an access token to finally call the respective Microsoft graph APIs.
Now we do not know if we are trying to attack this wrongly or whatever. Do you have any idea what we are missing here? Thanks in advance and I hope someone can shed light in this matter.
UPDATE:
We were able to have some progress. After some time, we bumped in the azure active directory portal. We are now able to get an access token using this URL.
https://login.microsoftonline.com/<directory-id>/oauth2/token
Now when we are accessing the actual MS Graph API endpoint that we are supposed to call, we are receiving a 401 Unauthorized response even though we are using the obtained token from the previous API call. This is the URL that we are trying to get a response:
https://graph.microsoft.com/v1.0/me/calendar/calendarView?startDateTime=2018-08-01T00:00:00.0000000&endDateTime=2018-08-31T23:59:59.0000000
This is all being done via postman first.
UPDATE:
We tried to grant every permission possible in the Azure Active Directory portal and confirmed the consent at
https://login.microsoftonline.com/<domain>.onmicrosoft.com/adminconsent?client_id=<client-id>
but unfortunately we're still hitting the 401 Unauthorized wall. In Microsoft Graph Explorer, everything is working fine. So what could be missing in our postman implementation that MS Graph Explorer is doing implicitly? Thanks in advance for any help!
UPDATE
After further reading, we've found out some important details. First, we've found out that there are two sets of APIs from Microsoft. One is the Azure Active Directory API and the other is the Microsoft Graph API. Both APIs use the same URL to get access tokens by using client credentials. Below is the URL:
https://login.microsoftonline.com/<directory-id>/oauth2/v2.0/token
Substitute the with your personal data from azure portal. Using this URL to get an access token, you need to supply some data in the request body.
client_id - client id of registered application in azure portal
client_secret - secret key of registered application in azure portal
grant_type - 'client_credentials' --> meaning you'll get an access token by using client credentials
scope - 'https://graph.microsoft.com/.default' or 'https://graph.windows.net/.default' --> this controls which API are you going to access. The first one is to access Microsoft Graph API and the other is to access Azure Active Directory API.
We are now able to get an access token and use it to access the actual API that we need. Below is the URL of the said API:
https://graph.microsoft.com/v1.0/users/<azure-tenant-name>.onmicrosoft.com/calendar/calendarView?startDateTime=2018-08-01T00:00:00.0000000&endDateTime=2018-08-31T23:59:59.0000000
Notice that the URL does not use /me because upon reading using it required a signed in user. Unfortunately we are still getting the 401 Unauthorized error but the errors did change now. We are getting to errors intermittently. Sometimes the API call would return one or the other alternately. Below are the return of the API calls.
{
"error": {
"code": "InvalidTenant",
"message": "The tenant for tenant guid '<directory-id-goes-here>' does not exist.",
"innerError": {
"request-id": "<some-request-id>",
"date": "2018-08-22T04:29:27"
}
}
}
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "<some-request-id>",
"date": "2018-08-22T04:54:11"
}
}
}
We feel we've moved a step forward. We're still not getting what we need though. Now the mystery are these 2 API call responses. What could be the reason of this? Thanks in advance for anybody's help
UPDATE
Upon even further reading we've discovered that there are authentication flows to get an access token. Depending on the API that you want to call, some authentication flows will not work on it because they need more details and security to execute themselves. So we've tried:
Client Credential Grant
Resource Owner Credential Grant
Authorize Code Grant
But still, unfortunately, we are still stuck in the previous error. We are getting 401 Unauthorized and the response payload is either InvalidTenant or UnknownError.
I just went through a similar problem yesterday, the 401 Unauthorized error.
I was trying to access the calendar of an employee via Microsoft's Graph API, but I was receiving the same response as you.
Resquest:
https://graph.microsoft.com/v1.0/users/employee-email/calendarview?startdatetime=2018-10-21T00:00:00Z&enddatetime=2018-10-27T23:59:59Z&$select=subject,categories,start,end,sensitivity
Response:
{
"error": {
"code": "UnknownError",
"message": "",
"innerError": {
"request-id": "<request-id>",
"date": "<date>"
}
}
}
Then I decided to check if had the Office 365. He didn't. I'm just a developer, so I ask the guys from infrastructure to install Office 365 on the empleyee's machine, or add him to an enterprice account, or something like that.
After they finished, the requests to his calendar worked just fine :)

Google calendar push notification : Unauthorized webhook call

Currently we are in the process of developing one iPhone application that deals with google calendar. There was need of syncing calendar events to the server side. Everything works fine.
But for push notification , we are following this process
Whenever we post request to :
https://www.googleapis.com/calendar/v3/calendars/email#gmail.com/events/watch
with parameters
"id":Unique string ( channel id) ,
"type": "web_hook",
"address": "https://abc-api.herokuapp.com/user/notifications"
In the header , we are sending
Authorization : **Bearer 'Access_token'**
and content type : json
We already added domain as authorized domain in the google api console
Access_token is user's account access token .
We are getting "Unauthorized webhook call" error.
{
"error": {
"errors": [
{
"domain": "global",
"reason": "push.webhookUrlUnauthorized",
"message": "Unauthorized WebHook callback channel: https://abc-api.herokuapp.com/user/notifications"
}
],
"code": 401,
"message": "Unauthorized WebHook callback channel: https://abc-api.herokuapp.com/user/notifications"
}
}
Anyone here who can help us to solve the issue ?
You might want to check this post, providing solution like verifying if your domain have a valid (not self-signed) SSL license. Also in google-api-php-client GitHub, instead of setting https://example.com/google/push (resulted in Unauthorized WebHook callback channel) or https://www.example.com/google/push (allowed me to successfully open channel, and object has been returned, however webhook has not been fired) as address they tried https://www.example.com/google/push/index.php and worked.
One potential issue is if you're testing in Google's "try it" section of the documentation. It's not stated, but this particular request does not work there.
Otherwise, there are a few things that need to happen with the domain you are supplying in the address. First, you need to make sure its verified in the google developers console for the application you are hitting the api with. Additionally, you need to add the website property to your search console (even if its just an api) and verify ownership.
Also, once you get past the unauthorized address issue, you will get another error requiring a resourceId be supplied.

Resources