3

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:

  1. Register an App in the Azure portal and create a Client Secret for it.
  2. Add all the permissions I need and grant them access:

    Add needed permissions and grant them admin access

  3. 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??)

    confirm permissions using admin credentials

  4. Get an access token (with success!):

    Access token obtained

  5. Try to read users (with success):

    users list obtained with success

  6. Try to read my own emails (without success):

    no luck with own emails

  7. Try to read somebody else's emails (the user was invited to access the app as a guest, but still, no success):

    no luck trying to read guest's emails

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:

enter image description here

These are the users added to the tenant:

enter image description here

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).

Luis Gouveia
  • 8,334
  • 9
  • 46
  • 68

3 Answers3

4

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.

Marc LaFleur
  • 31,987
  • 4
  • 37
  • 63
  • 1
    If I understood it right, you told me 2 things: 1 - "You cannot read emails that do not belong to an O365 subscription inside your Azure AD" and 2 - "outlook.com accounts don't allow all permissions". The 1. is upsetting, because that was precisely what I needed (I thought inviting users as guests was enough). The 2. is not a problem because according to https://docs.microsoft.com/en-us/graph/permissions-reference Mail.Read operation is valid for Outlook.com accounts. Can you confirm I understood you right, and also that the 'common' endpoint is not an option, before I grant you the bounty? – Luis Gouveia Dec 06 '19 at 14:39
  • 1
    If you're using Delegated Scopes (`authorization_code` grant) then you can use `Mail.Read` for both O365 and Outlook.com. If you are using Application Scopes than you can _only_ connect to O365 (there is no mechanism to receive Admin Consent for Outlook.com). – Marc LaFleur Dec 06 '19 at 17:32
  • 1
    If you need to be able to read messages from external O365 and Outlook.com mailboxes, then you need to use Delegated permission scopes and have the user authenticate interactively. – Marc LaFleur Dec 06 '19 at 17:34
  • 1
    Now I fully understood: I could only access Outlook/external O365 if the user would authenticate interactively. As I need to use a background process without presenting the log-in pop-up, I can only access emails inside my internal O365. Thank you, bounty granted! :) – Luis Gouveia Dec 09 '19 at 11:35
  • I'm actually working on something similar..with client_credentials flow. I have one personal microsoft account connected to the outlook and Azure active directory tenant. Have registered my application. Have a paid office 365 license and a free trial Azure AD account (with same MS account). Still it throws the error "OrganizationFromTenantGuidNotFound","message":"The tenant for tenant guid '' does not exist." – Kingshuk Mukherjee Mar 04 '21 at 16:22
  • @KingshukMukherjee: Please post this as a distinct question so it can get attention (and an answer). Make sure you include the type of accounts, how you registered your app, and the calls you're attempting to use for obtaining a token. – Marc LaFleur Mar 04 '21 at 16:53
  • @MarcLaFleur Sure will do that. Thanks...!! I know I might be doing something wrong. Just not able to pinpoint – Kingshuk Mukherjee Mar 04 '21 at 21:14
2

/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?

juunas
  • 54,244
  • 13
  • 113
  • 149
  • 1
    thank your for your answer. The user I'm trying to access is one of the users I added to the tenant, but I don't know if this answers your question. I added 2 new screenshots at the end of my question with more details. Do you see anything wrong? I cannot access any of the 3 user's emails... – Luis Gouveia Nov 28 '19 at 10:03
  • 2
    If they don't have Office 365 in your Azure AD tenant, the Microsoft account emails can only be accessed if your app uses the "common" endpoint of v2. Not the one with your tenant id. You are getting a token which is in the context of your AAD tenant. So you are trying to get emails that they have stored in your tenant. – juunas Nov 28 '19 at 10:35
  • 1
    I had already tried using 'common' instead of the tenant, but as I couldn't make any call (including https://graph.microsoft.com/v1.0/users/) I started using the tenant. Your suggestion made me test it again and I found out there's a problem in the adminconsent step (I didn't notice before): <> I've been searching the web but I still have no clue on what the problem is. – Luis Gouveia Nov 28 '19 at 11:40
  • 2
    Your app needs to be set to support personal Microsoft accounts as well. There is an option to allow either just your org, any org, or any org and personal accounts – juunas Nov 28 '19 at 11:57
  • 1
    I think I have that option in place as in the Authentication tab I could read the following: – Luis Gouveia Nov 28 '19 at 12:15
2

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.

Luis Gouveia
  • 8,334
  • 9
  • 46
  • 68