Microsoft.Exchange.WebServices.Data (401) Unauthorized error

Jose Correa 1 Reputation point
2022-02-25T20:04:39.793+00:00

I have a c# application that is getting the following error:

Error: Microsoft.Exchange.WebServices.Data.ServiceRequestException: The request failed. The remote server returned an error: (401) Unauthorized

The app failes on the following line: FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);

the following is the code


using System;
using System.IO;
using Microsoft.Exchange.WebServices.Data;
using Microsoft.Identity.Client;
using System.Configuration;

namespace csGet_Email_Attachment
{
    class Program
    {
        static void Main(string[] args)
        {
            ExchangeAuth xchg = new ExchangeAuth();
            xchg.ExchangeStuff();
        }
    }
}

class ExchangeAuth
{
    public void ExchangeStuff()
    {
        // Using Microsoft.Identity.Client 4.22.0
        var cca = ConfidentialClientApplicationBuilder
            .Create(ConfigurationManager.AppSettings["appId"])
            .WithClientSecret(ConfigurationManager.AppSettings["clientSecret"])
            .WithTenantId(ConfigurationManager.AppSettings["tenantId"])
            .Build();

        // The permission scope required for EWS access
        var ewsScopes = new string[] { "https://outlook.office365.com/.default" };

        try
        {
            //Make the token request
            //var authResult = await cca.AcquireTokenForClient(ewsScopes)
            var authResult = cca.AcquireTokenForClient(ewsScopes).ExecuteAsync().Result;

            Console.WriteLine("\n\nHit 'ENTER' to continue...");
            Console.ReadLine();

            // Configure the ExchangeService with the access token
            var ewsClient = new ExchangeService();
            ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
            ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);

            //Impersonate the mailbox you'd like to access.
            ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "******@autonation.com");

            int retint = GetAttachments(ewsClient);

        }
        catch (MsalException ex)
        {
            Console.WriteLine($"Error acquiring access token: {ex}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex}");
        }

        if (System.Diagnostics.Debugger.IsAttached)
        {
            Console.WriteLine("Hit any key to exit...");
            Console.ReadKey();
        }
    }
    private static int GetAttachments(ExchangeService service)
    {
        // Return a single item. 
        ItemView view = new ItemView(1);
        // Item searches do not support Deep traversal.
        view.Traversal = ItemTraversal.Shallow;
        view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);

        DateTime now = DateTime.Now;             // Use current time
        String strSubject = "D###### Daily Report";

        SearchFilter.ContainsSubstring subjectFilter = new SearchFilter.ContainsSubstring(ItemSchema.Subject, strSubject, ContainmentMode.Substring, ComparisonMode.IgnoreCase);

        String emailaddr = "@vps.#######.com";

        SearchFilter.ContainsSubstring fromEmailAddrFilter =
            new SearchFilter.ContainsSubstring(EmailMessageSchema.Sender, emailaddr);

        SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, subjectFilter, fromEmailAddrFilter);

        // Find the first email message in the Inbox that has attachments. This results in a FindItem operation call to EWS. 
        FindItemsResults<Item> results = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);

        if (results.TotalCount > 0)
        {
            EmailMessage email = results.Items[0] as EmailMessage;

            // Request all the attachments on the email message. This results in a GetItem operation call to EWS. 
            email.Load(new PropertySet(EmailMessageSchema.Attachments));

            String Outfile = @"C:\\temp\\DIEmailAudit.csv";
            foreach (Attachment attachment in email.Attachments)
            {
                if (attachment is FileAttachment)
                {
                    FileAttachment fileAttachment = attachment as FileAttachment;

                    // Load the file attachment into memory. This gives you access to the attachment content, which  
                    // is a byte array that you can use to attach this file to another item. This results in a GetAttachment operation 
                    // call to EWS. 
                    fileAttachment.Load();
                    Console.WriteLine("Load a file attachment with a name = " + fileAttachment.Name);
                    if (File.Exists(Outfile))
                    {
                        File.Delete(Outfile);
                    }
                    // Load attachment contents into a file. This results in a GetAttachment operation call to EWS. 
                    fileAttachment.Load(Outfile);

                }
                else // Attachment is an item attachment. 
                {
                    ItemAttachment itemAttachment = attachment as ItemAttachment;

                    // Load the item attachment properties. This results in a GetAttachment operation call to EWS. 
                    itemAttachment.Load();
                    Console.WriteLine("Loaded an item attachment with Subject = " + itemAttachment.Item.Subject);
                }
            }
        }
        else
        {
            return (-1);
        }
        return (0);
    }
    static string getAppSettings(String ConStr)
    {
        return ConfigurationManager.AppSettings[ConStr];
    }

}
Microsoft Authenticator
Microsoft Authenticator
A Microsoft app for iOS and Android devices that enables authentication with two-factor verification, phone sign-in, and code generation.
8,318 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
11,338 questions
Exchange Server Development
Exchange Server Development
Exchange Server: A family of Microsoft client/server messaging and collaboration software.Development: The process of researching, productizing, and refining new or existing technologies.
573 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Glen Scales 4,441 Reputation points
    2022-03-02T02:53:26.573+00:00

    In your Application registration you need to have given the full_access_as_app Application permission https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth . You can check if that is being successfully returned when you acquire you application by using https://jwt.io/ to look at you access token and you should see

    179065-image.png

    Its also a good idea to the set the X-AnchorMailbox Header to ensure your requests get routed correctly eg

    ewsClient.HttpHeaders.Add("X-AnchorMailbox", "******@autonation.com");

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.