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];
}
}