I'm trying to implement checking availability for specific user (actually a room) in O365 calendar. I'm using Graph API as it's recommended by Microsoft.
My first approach was using POST on https://graph.microsoft.com/v1.0/me/findMeetingTimes with the message body prepared according to template given in Graph API Explorer. On the API Explorer everything seems to work fine but when I try to run exactly the same request with my applications token I receive 403:
{
"error": {
"code": "ErrorAccessDenied",
"message": "Access is denied. Check credentials and try again.",
"innerError": {
"request-id": "b130177d-e138-4cc7-8e72-5d3529a9dc24",
"date": "2017-03-21T08:47:10"
}
}
}
I checked the app's delegated permissions in AAD and they seem to be fine. For Microsoft Graph those are granted:
Calendars.ReadWrite.Shared
Calendars.Read.Shared
Calendars.ReadWrite
Calendars.Read
I get exactly the same response (403) when I try to simply list user's events: https://graph.microsoft.com/v1.0/users//events In Graph API Explorer 500 is returned.
I found the following bug description: https://github.com/microsoftgraph/microsoft-graph-docs/issues/559 (and probably this one too) Is it related with the issues above?
Any clue what I might be doing wrong?
Is there any other way to achieve the same using different endpoint or API assuming that I still want to use oAuth for authorization?
I will be grateful for any hint
Update: Outlook Calendar API seems to work. Still appreciate any ideas why Graph API doesn't?
The FindMeetingAPI needs A work or a school account . If you are logging in using your personal email ID , you might not be able to login. Moreover , you need to set permissions to Calendars.Read Calendars.Read.All Calendars.ReadWrite User.Read"
Related
Within our department we have a Classic ASP website that has been using our corporate Google accounts for authentication and to insert events into our Google Calendars. The organisation has just switched from Google to Office 365 and I'm trying to switch the code to use Outlook instead - with no success.
I can use the access token to GET https://graph.microsoft.com/v1.0/me and see the basic profile, but if I try to read calendar events or send an e-mail I see the message:
"error": {
"code": "NoPermissionsInAccessToken",
"message": "The token contains no permissions, or permissions can not be understood."
I created an Azure account with my personal Microsoft account and added an application. I added my colleagues and my corporate account as guest users. I set the permissions required and did the admin consent thing:
I then followed the steps on this page.
I first visit https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/authorize, including the following query items:
client_id={client id}
response_type=code
redirect_uri={our URL}
response_mode=query
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={number}
This returns a "code", which I send to https://login.microsoftonline.com/{tenant id}/oauth2/v2.0/token, including:
grant_type=authorization_code
client_secret={client secret}
client_id={client id}
scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
state={same number as above}
redirect_uri={same URL as above}
code={code returned from /authorize}
This returns the id, access and refresh tokens. If I decode the access token using https://jwt.ms/, it seems to contain the appropriate audience and scope:
"aud": "https://graph.microsoft.com"
"scp": "Calendars.ReadWrite email Mail.Send openid profile User.Read"
...although I notice that there is no "roles" entry, which I see in some of the documentation. Is that an issue?
I then send the access token to https://graph.microsoft.com/v1.0/me with the following headers:
"Authorization", "Bearer {access token}"
"Host", "graph.microsoft.com"
"Content-Type", "application/json"
"Prefer", "outlook.timezone Europe/London"
That will return my e-mail address, etc., but if I change the URL to anything else, such as /me/photo/$value, /me/calendar/events, or try to send an e-mail I'm told that there are no permissions in the token.
I see that there are other similar questions, but they are mostly for the client_credentials flow (I'm not sure that makes any difference), and none of the answers has helped me resolve my problem.
Can someone please let me know if I've obviously missed anything - or I'm going about this in the wrong way to access Graph data on the client side? It seemed so straightforward with Google, but I'm finding the Microsoft documentation and examples a bit less detailed.
Adding guest users is meaningless.
What you have done is Admin consent for the Azure AD with your personal Microsoft account.
What you actually need to do is Admin consent for the target Azure AD/ O365 tenant.
Construct a consent link as following:
https://login.windows.net/{tenant ID of the target Azure AD}/oauth2/authorize?response_type=id_token&client_id={client ID}&redirect_uri={reply url}&response_mode=form_post&nonce=a4014117-28aa-47ec-abfb-f377be1d3cf5&resource=https://graph.microsoft.com&prompt=admin_consent
Access it in a browser and log in with an admin account of target Azure AD.
Another issue is that you are using Get access on behalf of a user. So you have to assign Delegated permissions rather than Application permissions in the Azure AD app.
In graph explorer the https://graph.microsoft.com/v1.0/me?$select=birthday endpoint gives me the example profile birthday
but when I try it with my account I receive this error
{
"error": {
"code": "ResourceNotFound",
"message": "Resource not found.",
"innerError": {
"request-id": "37e1643d-0bfd-46a4-8b48-70a4922f2952",
"date": "2017-12-29T21:33:16"
}
}
}
even though it returns my profile with the /me endpoint. I believe it has all the same scopes as the example and I checked all the .read scopes to make sure it had everything needed.
My birthday is in my profile and I am able to get my birthday from the deprecated live api with the wl.birthday scope but not the new graph api.
Thanks for pointing this out. Looks like we need to update our documentation. I filed this doc issue to track. Some user properties are only available for commercial (work or school) accounts (i.e. AAD based), through Microsoft Graph. Microsoft Graph, when signed in though a consumer account, has limited access to the same data that is exposed in the deprecated live API. I'll check if this particular item can be fixed.
Hope this helps,
I'm trying to develop an app in my enterprise and I've followed this tutorial to get access to the AD users information. Meaning:
I created an app in https://apps.dev.microsoft.com/
I set User.Read.All in Application Permissions and User.Read in Delegated Permissions
With this done I'm able to successfully login (Azure AD OAuth2 with https://graph.microsoft.com/ as resource and User.Read as scope) and get a correct response from https://graph.microsoft.com/v1.0/me.
Ask the Admin for the Delegated Permissions
With this, my admin can see in the azure portal that my App has both permissions consented by himself.
This is working because I asked a coworker to log in and I could get a correct response from https://graph.microsoft.com/v1.0/me even though he wasn't even prompted to consent this (Before the admin consenting the permissions the user was prompted)
Request a token from https://login.microsoftonline.com/common/oauth2/token with client_credentials as a response_type
Receive the token!
Do a GET request to https://graph.microsoft.com/v1.0/users and receive:
{
"error": {
"code": "Authorization_IdentityNotFound",
"message": "The identity of the calling application could not be established.",
"innerError": {
"request-id": "b2d9ec62-0b65-44eb-9e0f-4aec52b45750",
"date": "2017-03-22T19:19:48"
}
}
}
Furthermore, doing a request to https://graph.microsoft.com/v1.0/me returns:
{
"error": {
"code": "BadRequest",
"message": "Current authenticated context is not valid for this request",
"innerError": {
"request-id": "047e2ba9-a858-45fc-a0dd-124e1db503f3",
"date": "2017-03-22T19:39:25"
}
}
}
Which leads me to believe that Microsoft knows this token and knows it is not impersonating any user.
I've been looking for documentation on Azure AD and Microsoft Graph authentication but I only find blog posts and all seem outdated (although most features are in preview).
If you could point me in the right direction I would thank you.
I've also found this and this similar questions on SO but they all remain unanswered.
Update, after this answer
Thank you, Dan,
I've used my organization domain name and I'm also able to get a token.
Now the response from https://graph.microsoft.com/v1.0/users/ is:
{
"error": {
"code": "Authorization_RequestDenied",
"message": "Insufficient privileges to complete the operation.",
"innerError": {
"request-id": "3f190b47-73f5-4b29-96f9-54ed3dbc3137",
"date": "2017-03-23T11:07:15"
}
}
}
Which makes no sense because in the azure portal I have User.Read.All as Application Permission (already consented by the admin).
I think the problem is with the request for the token, that returns successfully no matter the scope I send, even if I made one up.
For Example:
POST https://login.microsoftonline.com/<domain>/oauth2/token
client_id:*******
client_secret:*******
resource:https://graph.microsoft.com/
grant_type:client_credentials
scope:Foo.Bar
Returns:
{
"token_type": "Bearer",
"expires_in": "3599",
"ext_expires_in": "0",
"expires_on": "1490271617",
"not_before": "1490267717",
"resource": "https://graph.microsoft.com/",
"access_token": *****
}
I had two problems, both not covered documentation:
For client credentials, if the app belongs to a work or school (organization) context then for https://login.microsoftonline.com/common/oauth2/token replace common with a tenantId or domain name (thanks to Dan Kershaw)
For https://graph.microsoft.com/v1.0/users or https://graph.microsoft.com/v1.0/users/{id | userPrincipalName} you need Directory.Read.All permission.
Note:
User.Read.All is relevant for Microsoft to stop requesting permissions (delegation) to the user when you ask for User.Read in the OAuth workflow. Check this and other Permission related issues in the Release Notes.
I've added this issue to the Microsoft Graph Docs!
The /me segment is a shortcut or alias for the currently signed-in user. The request to /me will never work with an application token, because it doesn't contain any user context (or signed in user) - and hence the error. We might be able to improve this error though ;)
I believe when using the client credentials flow, you need to specify the actual tenant that you want a token for.
If you're app is performing this operation in a work or school (organization) context then for https://login.microsoftonline.com/common/oauth2/token replace common with a tenantId or domain name, and see if that works.
If you are following https://learn.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds it looks like we might have a couple of doc bugs in there that we need to fix...
Hope this helps,
We would like to automatically create a project ID and install our ULAPPH Cloud Desktop application using the App Engine Admin API (REST) and Golang.
https://cloud.google.com/appengine/docs/admin-api/?hl=en_US&_ga=1.265860687.1935695756.1490699302
https://ulapph-public-1.appspot.com/articles?TYPE=ARTICLE&DOC_ID=3&SID=TDSARTL-3
We were able to get a token but when we tried to create a project ID, we get the error below.
[Response OK] Successful connection to Appengine Admin API.
[Token] { "access_token" : "TOKEN_HERE", "expires_in" : 3599, "token_type" : "Bearer" }
[Response Code] 403
[Response Body] { "error": { "code": 403, "message": "Operation not allowed", "status": "PERMISSION_DENIED", "details": [ { "#type": "type.googleapis.com/google.rpc.ResourceInfo", "resourceType": "gae.api", "description": "The \"appengine.applications.create\" permission is required." } ] } }
We are just using the REST API calls. Request for token was successful as you can see above and the scope is ok as well. Now, when we posted the request to create application, we are having the error that says "appengine.application.create" permission required.
How do we specify the permission?
What are the possible reasons why we are getting that error? Do we missed to send a field in JSON or in query?
As per below link, we just need to pass the json containing the id and location. We also just need to pass the token in the Authorization header. The same logic I have used successfully in accessing Youtube, Drive APIs etc so not sure what needs to be done since I have followed the docs available.
I have also posted the same issue in Google Groups and now waiting for their reply.
It seems you've given no details about how you set up the account you're using to authorize the request. You'll need to make sure the appengine.applications.create permission is given to the account you're using, as mentioned in the error text. You can use the Google Identity and Access Management (IAM) API for this.
(by the way, I'd given this answer in the original thread, although you didn't reply or seem to take action on it. check it out! this is likely the solution you need!)
I have been using outlook rest api's to read/create/update calendar events of outlook account.
Followed all the steps https://dev.outlook.com/RestGettingStarted/
It works very well for the subscription account's.
But the api does not work to load the calendar events of my personal outlook account ex: phani.xxx#outlook.com.
API responds with below error:
"error": {
"code": "ErrorMissingEmailAddress",
"message": "When making a request as an account that does not have a mailbox, you must specify the mailbox primary SMTP address for any distinguished folder Ids."
}
I have tried the same with outlook sandbox got the same response.
Any help on this to get this api working for any outlook account. Will be highly appreciated.
This is likely due to your account not yet being enabled for the REST API. There's an issue with the v2 endpoint not returning the proper error message in this case.