2

I need to read a certain email but a different account.

The first example works

        string applicationClientID = "aaaaaaaaaaaaaaaaaaaa";
        string directoryTenantID = "dddddddddddddddddd";
        string secretID = "sssssssssssssssssssssss";

//Example 01: OK

        string email = "emailRead@outlook.com"; //WORKS: account 
        that will read the email = emailRead@outlook.com

//Example 02: Error need to read emailRead@outlook with account countService@outlook.com

        string email = "emailRead@outlook.com"; // DOES NOT WORK: 
        account that has permission to read email:  
        countService@outlook.com

        var credentials = new ClientSecretCredential(
        directoryTenantID, applicationClientID, secretID,
        new TokenCredentialOptions { AuthorityHost = 
        AzureAuthorityHosts.AzurePublicCloud });

        GraphServiceClient graphServiceClient = new 
        GraphServiceClient(credentials);

        var inboxMessages = await graphServiceClient
            .Users[email]
            .MailFolders["inbox"]
            .messages
            .Request()
            .Expand("attachments")
            .Top(20)
            .GetAsync();

//I get the following message: Message: Access to OData is disabled.

Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
user10529055
  • 29
  • 1
  • 1
  • 4
  • Do you have any progress sir? – Tiny Wang May 20 '22 at 05:03
  • he question is whether it is possible to read the emailCompany@contoso.onmicrosoft.com through the accountCompany@contoso.onmicrosoft.com another similar scenario: if I have 2 registered users: user1@contoso.onmicrosoft.com user2@contoso.onmicrosoft.com and has an email: email@contoso.onmicrosoft.com how would i read email@contoso.onmicrosoft.com through user1 or user2? – user10529055 May 23 '22 at 19:39
  • Firstly, it's possible to read emails contained in `email@contoso.onmicrosoft.com` on behalf of user1 or user2. The whole progress should look like this: provide microsoft authentication to let user1/user2 sign in first, then your app can based on the signing in information to generate an access token to call graph api and then get the emails. On this scenario, you can refer to [this sample](https://github.com/Azure-Samples/active-directory-aspnetcore-webapp-openidconnect-v2/tree/master/2-WebApp-graph-user/2-1-Call-MSGraph). – Tiny Wang May 24 '22 at 05:01
  • Another scenario is that you don't want to provide a sign in module and you just want to read all the emails inside `email@contoso.onmicrosoft.com`, then you may refer to my code in the post, it used client credential flow so it doesn't need user to sign in, it generated access token on behalf the application itself. And please note, the 2 scenarios require different api permission, the first one require `Delegate` api permission and this one require `Application` [api permission](https://docs.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0&tabs=http#permissions). – Tiny Wang May 24 '22 at 05:04

2 Answers2

4

I think your code should work, except messages should be Messages. Here's my test result.

enter image description here

Firstly, when we want to check emails for a specific email account, we need to use client credential flow just like you used.

var scopes = new[] { "https://graph.microsoft.com/.default" };
var tenantId = "tenant_name.onmicrosoft.com";
var clientId = "azure_ad_appid";
var clientSecret = "client_secret";
var clientSecretCredential = new ClientSecretCredential(
    tenantId, clientId, clientSecret);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var inboxMessages = await graphClient
                        .Users["tinywang@hanxia.onmicrosoft.com"]
                        .MailFolders["inbox"]
                        .Messages
                        .Request()
                        .Expand("attachments")
                        .Top(20)
                        .GetAsync();
Tiny Wang
  • 10,423
  • 1
  • 11
  • 29
  • Hi, can you please tell us the settings are required in Azure portal to run this code block. – Shiv Shankar Maiti Dec 12 '22 at 18:00
  • The scope I used `https://graph.microsoft.com/.default` means I'm using `application api permission`, so we need to [give api permission](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#application-permission-to-microsoft-graph) in Azure AD. @ShivShankarMaiti – Tiny Wang Dec 13 '22 at 02:00
  • When you give api permission you must have an Azure AD application now, or you have to [create an Azure AD app](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#register-an-application-with-azure-ad-and-create-a-service-principal) and add [client secret](https://learn.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret) for it. – Tiny Wang Dec 13 '22 at 02:02
  • Thanks for your quick response. Actually my client has allowing us to delegates permission. Can help me bit what changes I have to do in your mentioned code? – Shiv Shankar Maiti Dec 15 '22 at 13:37
  • you can't use my code when you use delegate permission. using delegate permission means you have to make your users sign in so that they can be authenticated and authorized to get the delegate permission. Pls find a [sample here](https://learn.microsoft.com/en-us/azure/active-directory/develop/sample-v2-code). @ShivShankarMaiti – Tiny Wang Dec 16 '22 at 02:08
1
  • The problem might be with the Application Access Policy.
  • Generally, if you use Application Permissions in OAuth for Microsoft 365, you can use the following instructions to further narrow down the permissions: Limiting application permissions to specific Exchange Online mailboxes
  • Permissions for Microsoft Graph applications (You might not require all of these):
    Mail.Read
    Mail.ReadBasic
    Mail.ReadBasic.All
    Mail.ReadWrite
    Mail.Send
    MailboxSettings.Read
    MailboxSettings.ReadWrite
    Calendars.Read
    Calendars.ReadWrite
    Contacts.Read
    Contacts.ReadWrite
  • When an API call is refused access due to a specified application access policy, you may see the following error.
{
"error": {
    "code": "ErrorAccessDenied",
    "message": "Access to OData is disabled.",
    "innerError": {
        "request-id": "<request GUID is here>",
        "date": "<UTC date format here>"
    }
}

  • If your app's Microsoft Graph API calls return this error, check with the organization's Exchange Online administrator to make sure your app has authorization to access the mailbox resource.
  • Helpful Powershell commands :
    Test-ApplicationAccessPolicy
    Get-ApplicationAccessPolicy
    New-ApplicationAccessPolicy
    Remove-ApplicationAccessPolicy
    Set-ApplicationAccessPolicy