Microsoft Graph schemaExtensions Authorization_RequestDenied - microsoft-graph-api

I'm trying to use Microsoft Graph from my app via REST API graph.microsoft.com/beta/schemaExtensions
Here is what I did:
Register app at https://apps.dev.microsoft.com
Checked for all Delegated and Application authorizations
Got access token without a user based on OAuth Client Credentials Grant flow
Asked for Admin Consent with access token retrieved from point 3. and it was successful using https://login.microsoftonline.com/tenant/adminconsent?client_id=xxx&state=12345&redirect_uri=http://localhost:8081
POST to /beta/schemaExtensions with access token retrieved from point 3. and I have this error:
Authorization_RequestDenied - Insufficient privileges to complete the operation
So here are my questions, hoping someone could help me:
How do I check if delegate authorization is ok after Admin Consent request?
Which privileges are missing to use schemaExtensions?
My app should work without a user, it's the preferred approach.

Couple of things here.
Extensions is GA and available on the /v1.0 version. Please use that instead of /beta.
We don't support schema extension registration using application permissions. It requires the Directory.AccessAsUser.All permission today (we're also investigating if there's another less privileged permission we can use here) per the create schema extensions topic.
Registering a schema extension can be a separate process from your application actually using the extension to create custom data on target object instances.
As such we are making a change (should be available shortly) to allow you to register and manage schema extensions for your app using Graph Explorer. There is also a user voice request to have a UI experience in app registration for schema registration/management. Please vote for this if it's important to you.
I'll update this post once Graph Explorer supports registering and managing schema extensions.
Hope this helps,

To answer the follow up question, the calling user should have read/write access to add custom data to another user. However, you can use open extensions to add custom data using /me/extensions to calling user (as long as the app has user.readwrite or higher permissions).

Related

To read another users mailboxsettings with MSGraph does the application really need application level permissions?

I am trying to read a person's Out of Office text with MSGraph. I understand the only way to do this is by getting the person's mailbox settings as indicated here.
Is there another way to read a person's Out of Office Message?
Assuming there is no other way I then have read for example in this link that to call GET /users/{id|userPrincipalName}/mailboxSettings you need to have Application Permissions for MailboxSettings.Read, MailboxSettings.ReadWrite. Is this still the case? It does not make sense to me that you need Application level permissions. Is there not a delegated (admin consent required) MailboxSettings.Read.All??? The problem is that most IT departments will be hesitant (or pigs are going to fly before some IT departments) give an application this permission to run without a signed in user.
Alternatively, I see that there is a User property of mailboxsettings, thus using the $select query parameter you can call this https://graph.microsoft.com/v1.0/users/{id}?$select=mailboxSettings does or should this work with the User.Read.All.
UPDATE in accordance with the suggestion below I have added 2 suggestions to the MSGraph user voice.
A person's out of office information should be included with their calendar / freebusy (getschedule) information.
There should be a Mailboxsettings.Read.All permission.
Please click on the link and vote them up if you agree.
No, there is no MailboxSettings.Read.All or MailboxSettings.Read.Shared. You can see the list at https://learn.microsoft.com/graph/permissions-reference#mail-permissions. I encourage you to request this as a feature at https://microsoftgraph.uservoice.com.
One possible approach given the currently available permissions around this API is to use app permissions and configure an app access policy to limit the mailboxes it can access - if that's the concern you're mentioning. I'm not clear on why it would be preferable to give a user account access to this info for all mailboxes in an org but not an app service principal.
It isn't included as part of User.Read.All by design. It's not really a property on the user, it's config stored in the mailbox. It's abstracted as a property in Graph, but it requires additional permissions to access.

Calling Microsoft Graph API from Azure Function to retrieve user's Contacts

I cannot find a good working sample that calls the Graph API and retrieves the user's contacts from within an Azure Function. Part of the issue is a lack of documentation and samples as this seems new-ish. Is this even possible? I am trying to create a function that can take a phone number and check against the user's contacts to see if the contact exists. So far, the only way I can achieve authentication is to use Postman to retrieve a token manually. That token didn't even work to retrieve the contacts. I know I am doing something wrong but I think what I really need is the big picture. I'm missing something. Thank you for your help.
The auth token binding may help at least with the act of getting the token. In this case, if it's on behalf of the user invoking the function, you'll want to use the identity: userFromRequest setup. Keep in mind that for debugging, you'd still have to acquire a user token for the app and attach that to calls to your function, but you can use the function app's /.auth/login/aad and /.auth/me endpoints for that.
Make sure that your application registration has the Contacts.Read permission. This is required for the contacts API.Today, the UX for App Service Authentication / Authorization today links to the existing permissions UX, which unfortunately uses different names for things. I'd recommend navigating directly to the AAD section of the portal and selecting App registrations (Preview). Find your app registration there (defaults to same as your app name), and browse through the API permissions there. That way the right names show up and will match the Graph docs.

Microsoft Graph API auhetication for service apps

We are developing a web application using Microsoft Graph, where the signed in user can, Export all the calendar events to a third party calendar Application. After this initial export, we need to keep the exported data in sync with calendar changes via service app (a scheduled task running on server). This need to be a multi tenant application, as people from different organizations should be able to use this service.
Right now we did the authentication using OAuth 2.0 and OpenID Connect as described in this sample. Later we understood that the access token we get using this method cannot be used in the service app without user interaction. Considering our scenario what is the best way to achieve this?
I have read about App-only authorization method to do this. If we use this authentication method, the app need to be consented by a tenant administrator and the these applications are quite powerful in terms of what data they can access in the Office 365 organization. Considering we are developing a product used by different organizations, will it be feasible to use this method?
To use the client credentials OAuth2.0 flow (aka "App-only" or service account access depending on who's documentation you're reading) the admin for each tenancy will need to specify which scopes your daemon process can have for users in their tenancy. The end users can't give these scoping rights to your code themselves (as far as I know at least).
One thing to watch out for is that currently Graph API doesn't allow you to mess about with calendars that are attached to Office 365 Groups if you're using the client credentials flow. This is a pain for us, so we've raised it as an issue that needs fixing in the Office 365 feedback system. if that's an issue for you or anyone else, please throw a few votes at it so that it gets more attention at Microsoft. :-)

Do I need OAuth2.0 to create a google account through the Admin SDK API?

Currently using the Provisioning API that is being depreciated April 20.
This is the current flow:
user (University Alumni) gets to our site http://alumni.columbia.edu/email
they click on Create My Account
they authenticate through our university WIND system using what we call their UNI
they land on a page mentioning that an email account UNI#caa.columbia.edu is ready to be created. They can pick an alias to UNI. They also need to enter a password to use the Chat and POP-mail features of Gmail.
they confirm the creation of the account. At this point the API is being called using https://www.google.com/a/feeds/, some data (email address, name, id) being saved in our database.
To log in, they come through our site, click on the login button, this will use the SSO and they get logged in.
Based on the flow above, do I need to use OAuth2.0?
Yes, you will need to authenticate with OAuth using the Installed Applications approach to do this. Instead of step 5 the way you currently have it, you'll need to call the API from a process on your server with an account that has (limited) admin credentials that can create the account with the Directory API. To do this, you'll need to persist the OAuth token information that the account will use to connect, and handle the code to refresh the token when it has expired.
The first time you run your code you'll need to manually authenticate that account to get your application the appropriate permissions so that they can be stored.
If you're hoping to not go too crazy with handling the authentication side of things and you're using .Net, I'd recommend checking out my project gShell that acts as a wrapper for the authentication and handles the token storing and refreshing for you. It's still a young project but it should fit your needs. Alternately, feel free to browse the code for an example on what to do.
If you plan on using Python, check out Google Apps Manager by jay0lee which is also a wonderful resource.

Using fusion tables with app inventor as a database

Easy to answer question ( I hope)
Need to use fusion tables with app inventor as a database but need to have every app access it without having to log in with user id.
Does app inventor have that functionality? Believe I need to set up API for 'installed applications' but do not know where in app inventor I need to enter the SHA1 code.
App is to 'anonymously' update database without needing to log in.
Thanks in advance
I don't think that this is possible with the built-in Fusiontables Controls, see also the notes in the Pizza Party tutorial:
NOTE about Sharing Fusion Tables: To share a FusionTable with others,
you have to invite each person individually, the same way you would
share a private google doc. There is no way to share write privileges
to a FusionTable with the public. Public access is restricted to
read-only.
However this is possible with the App Inventor - Fusiontable interface using the web component. To prepare the login free access, do a run with the interface with your login and store the received refresh token as variable in your app. Then you can build your app, publish it and run the interface with the stored authorization without need to login anymore. The user will then access your fusion table with owner permissions.
See also this similar question and here
Application 1 - Using Fusion Tables like a Database*
...
In other words, if you own a Fusion Table in your own account that you
want to serve as a database in your application, you simply need to
get the access and refresh tokens for that account, and use the access
token for all requests to Fusion Tables. When the access token
expires, a 401: Unauthorized message is returned, and the refresh
token can be used to request a new access token.
...
You can then securely save the access and refresh tokens somewhere
accessible by your application, and use them in your code to make the
requests to Fusion Tables.
EDIT: You now can find a running example here.
If you just need a database for your app, also consider using Google Cloud SQL which offers familiar MySQL functionality on the cloud. https://developers.google.com/cloud-sql/

Resources