添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

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" };
            //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, "correaj@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);
            return (-1);
        return (0);
    static string getAppSettings(String ConStr)
        return ConfigurationManager.AppSettings[ConStr];
												

@Jose Correa , Welcome to Microsoft Q&A,Since I don't have the AccessToken, I used NetworkCredential for your code. Then, there is no errors for me. Therfore, I have two suggestions.
First, you could check if your AccessToken is correct.
Second, you could use Email account to do it, like the following:

 ewsClient.Credentials = new NetworkCredential("jack147527@hotmail.com","jujun123.");  
						

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

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", "correaj@autonation.com");