Microsoft Graph API permissions in case of retrieving my own user profile - microsoft-graph-api

I would like to invoke the GET https://graph.microsoft.com/v1.0/me HTTP endpoint, but it is not obvious what API I need to grant to my application in order to have sufficient privileges for the given API call. It is also not clear, how the type of the current user impacta this HTTP call (is the user a member of the organization, or a guest user, etc.).
This is the page i was trying to pull information from: https://learn.microsoft.com/en-us/graph/api/user-get?view=graph-rest-1.0&tabs=http

For /me it is enough to grant User.Read permission, which is AFAIK the minimal permission possible for an app, it is "Sign In" basically. It is supported for all types of accounts (both "organization" and "external" accounts)
There is also a handy graph explorer tool, which shows which grants are required for which graph APIs. They are also well documented.
The graph explorer tool:
https://developer.microsoft.com/en-us/graph/graph-explorer

Related

Verify user has the "Global Reader" role in Azure AD

I created an app that displays SignInActivity pulled from a Microsoft Graph api query.
When running as a normal user it gives the error: User is not in the allowed roles.
To fix this error you need to give the user the "Global Reader" role within o365.
Questions:
Is there an App security scope that will allow a user to view SignInActivity even if they don't have the "Global Reader" role?
The app already has the scope AuditLog.Read.All. This was needed to run the query.
Is there a way to use Microsoft Graph api to verify a user has the "Global Reader" role?
You can check the scopes through Microsoft Graph Api by decoding the access token, you can try to login into https://developer.microsoft.com/en-us/graph/graph-explorer with work or school accounts (Azure AD), you can just look inside the access token to see a list of permissions by decoding the access token into https://jwt.io/

Does Microsoft Graph work without User.Read scope?

My question is, does Microsoft Graph work without User.Read scope ? I am not able to request the email profile openid permissions directly.
It throws AccessDenied error. So is User.Read pre requisite for email profile or openid ?
User.Read is just the delegated permission for getting the user profile using MS Graph Get User. If your app does not need to read the user profile you don't need this permission but in most cases you do because you app is acting on behalf of the user.
Does Microsoft Graph work without User.Read scope ?
No, but in most cases, you need the scope to read user profile and call /me endpoints.
You should check the api document to see if calling that api required User.Read permission.
For instance: I wanna call this api to list emails, and we can see that this api provides 2 kinds of permissions, one is for delegate, another is for application(this means client credential flow is supported). All the api permissions are listed here and we need to go to azure ad portal to add the api permission to your azure ad application which used to generate access token.
After generating the access token, you can user jwt decode tool to check if your access token contains correct scopes(for delegate permission) or roles(for application permission). Using a correct token to call the api will not lead to AccessDenied error. By the way, newly added permission may be deferrable to take effect.

How do I register a MSFT Oauth2 permission for e.g. SMTP AUTH when it isn't listed in AAD's resource API list

Could anyone explain how a MSFT Oauth2 client scope with a URI of https://outlook.office.com (needed for SMTP AUTH or IMAP, for example) can be specified in a corresponding AAD permission when outlook.office.com is not listed in the resource API list ?
MSFT push Graph (which does have e.g. an SMTP AUTH permission), but they have confirmed that SMTP AUTH and IMAP are implemented only in the outlook resource API. Testing confirms this: if the client uses a scope of https://graph.microsoft.com/SMTP.Send and an AAD Microsoft Graph permission of SMTP.Send, authentication fails. The acid test lies is the ‘aud’ claim in the Access token: if it is “00000003-0000-0000-c000-000000000000” (aka Graph) authentication fails whereas an ‘aud’ of https://outlook.office.com will succeed (other things being equal).
I would have thought naively that the client scopes and AAD permissions resource API should have the same URI.
I can’t see how granular permissions – where the AAD permissions are a superset of the client’s scopes and clients ask for the minimum they need at the time they need it – can work if I cannot specify the superset in AAD!
I have asked MSFT for enlightenment but no response.
=====
Additional tests:
If AAD Graph permissions are null and the client scope is just https://outlook.office.com/SMTP.Send, the access token has an ‘aud’ of https://outlook.office.com and an ‘scp’ of SMTP.Send, and authentication is OK.
But if the client scope also contains a Graph scope such as Mail.Send, ‘aud’ changes to 00000003-0000-0000-c000-000000000000 (aka Graph) and subsequent authentication fails with ‘incorrect credentials’. I would have expected a “scope asking for one token for two different resources” type error message from the token endpoint.
And, as would be expected, if the client scope is just SMTP.Send (or https://graph.microsoft.com/SMTP.Send; the Graph URI prefix being now the default) authentication fails with ‘incorrect credentials’
These are using the V2 authorisation and token endpoints – as recommended by MSFT.
====
Further comments in response:
#Allen Wu - I cannot find IMAP.AccessAsUser.All, POP.AccessAsUser.All and SMTP.Send listed under Exchange (API permissions => + Add a permission => Request API permissions /Microsoft APIs => Exchange or under Office 365 Exchange Online (API permissions => + Add a permission => Request API permissions / APIs my organization uses => Office 365 Exchange Online) . They are only listed under Graph. This leads to the weird situations that:
if a client uses (e.g.) SMTP.Send (or https://graph.microsoft.com/SMTP.Send) scope, authentication fails even though MSFT instruct (vide your last link) that the corresponding permission must be registered in Graph
if a client uses (e.g.) https://outlook.office.com/SMTP.Send scope (as instructed by MSFT), the client cannot add further https://outlook.office.com permissions (because the resource API is not listed) or use additional Graph scopes (because authentication fails and it would appear to be asking for one token to cover two APIs anyway)
Vide your comment “We see that the permissions are under Microsoft Graph in the Azure portal, but in fact the same has been added to the outlook endpoint”, MSFT could pre-empt much confusion (other StackOverflow posters have logged similar problems) if they simply listed the outlook.office.com API in AAD API permissions until Graph accessed a complete set of endpoints as well as permissions. I realise they want developers to use Graph, but the present situation is akin to being half-pregnant!
In this case, you just need to select the Microsoft graph permissions (SMTP AUTH or IMAP).
Currently when you need to get an access token, you can specify the scope as https://outlook.office.com/{SMTP AUTH or IMAP permission}.
I think the permissions are still in change. The Outlook permissions should be included in Microsoft Graph in the future.

"The tenant for tenant guid ... does not exist" when using client credentials flow (daemon) to access Microsoft Graph API

I want to access Microsoft Graph periodically from a console application in order to copy messages from an Outlook mailbox to a database.
In order to authenticate programmatically, I had to use the Microsoft Graph's "Client Credentials Flow".
These are the steps I had to take:
Register an App in the Azure portal and create a Client Secret for it.
Add all the permissions I need and grant them access:
Have an Admin confirm those permissions by accessing it for the first time. This is done using the following URL:
https://login.microsoftonline.com/{tenant}/v2.0/adminconsent
?client_id={app id}
&state=1234
&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient
&scope=https://graph.microsoft.com/.default
I received the following response:
admin_consent: True
tenant: ca566779-1e7b-48e8-b52b-68**********
state: 12345
scope**: scope: https://graph.microsoft.com/User.Read https://graph.microsoft.com/.default
(The scope might explain the problem described later here: Why do I only get User.Read when I've configured 13 different permissions??)
Get an access token (with success!):
Try to read users (with success):
Try to read my own emails (without success):
Try to read somebody else's emails (the user was invited to access the app as a guest, but still, no success):
I don't understand why I can't read Messages but I can read Users. It seems the permissions were completely ignored (I confirmed that I don't need any permission to read the users).
UPDATE
This is my tenant name:
These are the users added to the tenant:
Important: I don't own an office 365 subscription in my Azure AD. All these emails belong to a different AD.
The previous question "The tenant for tenant guid does not exist" even though user is listed on users endpoint? is similar to mine but I believe this is not a duplicate as my problem is slightly different and the proposed solution uses OAuth1 (I am using OAuth2).
Microsoft Graph can only access data within the tenant you have authenticated to. This means that you cannot access a mailbox from another tenant, even if that User is a guest in the tenant you authenticated to. Allowing this would violate the fundamental principle of data isolation in AAD/O365 tenants.
It is also important to note that AAD/O365 and Outlook.com are distinct platforms. Microsoft Graph's core value prop is a common API layer across AAD and MSA, but under the covers, they are calling into distinct backends.
Beyond data isolation and these being distinct platforms, Outlook.com simply does not support Application Permissions (Client Credentials). You can only access Outlook.com using delegated permissions, and even only a limited set of scopes are supported:
Not all permissions are valid for both Microsoft accounts and work or school accounts. You can check the Microsoft Account Supported column for each permission group to determine whether a specific permission is valid for Microsoft accounts, work or school accounts, or both.
With regards to which scopes are included, I suspect the issue here is that you don't have a license for O365 in this tenant. If it allowed you to consent without a subscription, this could (in theory) lead to apps unexpectedly receiving consent when/if a subscription got added later. That said, it is hard to tell without seeing an example of an actual token you're getting back (feel free to post one of you'd like me to look into this more).
Finally, juunas is also correct with regards to /me. The /me segment is an alias for "the currently authenticated user". Since you are not authenticating a user when you use Client Credentials, /me is effectively null.
/me won't work with a client credentials token.
What would /me refer to? There is no user involved so it cannot mean anything.
For the second problem, does this user have an Exchange Online mailbox in your tenant?
The accepted answer is the one that helped me out. However, I ended-up testing what I needed to test joining the :
Office 365 Developer Program (free)
This program will allow you to create an Azure Active Directory with up to 25 email accounts. It also allows you to create 16 fictitious email accounts with emails inside (by clicking one single button). You can use this infrastructure for 90 days for free.

Using Client Credentials with Microsoft Graph OneNote API on Office 365 Business

I am building an app (HTTPS calls from LabVIEW) that will update my enterprise OneNote notebooks on Office 365 without the need for any user interaction. Hence I have opted for using the Client Credentials flow and granting Application permissions in Azure AD to my app (Read and write all OneNote notebooks) through Microsoft Graph.
I have referred to the instructions mentioned in the following pages:
https://msdn.microsoft.com/en-us/office/office365/howto/onenote-auth-appperms
https://developer.microsoft.com/en-us/graph/docs/concepts/permissions_reference
https://learn.microsoft.com/en-gb/azure/active-directory/develop/active-directory-v2-protocols-oauth-client-creds
https://developer.microsoft.com/en-us/graph/docs/concepts/auth_v2_service
https://developer.microsoft.com/en-us/graph/docs/concepts/onenote-create-page
I am able to get an access token from Microsoft Graph but once I try to use it to update my notebooks by making a POST call to the URL
https://graph.microsoft.com/v1.0/me/onenote/pages
I get the error:
"The OneDriveForBusiness for this user account cannot be retrieved." Code - 30108
However, I am fully able to access OneDriveForBusiness online using the same account which created the app and the tenant ID of which I used to grant permissions. Can someone please clarify if there are certain restrictions regarding the type of O365 and OneDriveForBusiness subscriptions that are necessary for my requirements? Which particular subscription or their combinations thereof should allow me to achieve the flow I need?
You cannot use /me with Client Credentials. /me is an alias for /users/{currentUserId but since you're using Client Credentials, there is a User in context for the API to map that alias to. You are effectively calling /v1.0/users/NULL/onenote/pages in this case.
You need to explicitly specify the User you want to access:
/v1.0/users/{userId or userPrincipalName}/onenote/pages

Resources