Read an office 365 mailbox using Exchange web services - c#

I am using this below code but unable to read my office 365 Inbox emails from C# code. Once I get this working then later I would need to read emails from shared mailbox.
I’d really appreciate if someone could please help me in fixing this issue or guide me what am I missing here ?
If I use Url as Office365 one then getting this error: "The request failed. The remote server returned an error 401. Unauthorized "
If I use Url as casx16 one (found this in company's Q/A portal) then getting this error: " No mailbox with such GUID "
using Microsoft.Exchange.WebServices.Data;
public static void ReadMyMailbox_2()
{
ExchangeService exchangeService = new ExchangeService();
exchangeService.Credentials = new WebCredentials("ajain", "password ", "MS"); /// ajain is my MSID
// exchangeService.AutodiscoverUrl("a_jain#xyz.com", RedirectionUrlValidationCallback);
exchangeService.Url = new Uri("https://casx16.xyz.com/ews/exchange.asmx");
// exchangeService.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
FolderId mailbox = new FolderId(WellKnownFolderName.Inbox, "a_jain#xyz.com");
ItemView itemView = new ItemView(10);
FindItemsResults<Item> result = exchangeService.FindItems(mailbox, itemView);
foreach (var msg in result)
{
EmailMessage message = EmailMessage.Bind(exchangeService, msg.Id);
Console.WriteLine(message.Subject);
}
}

It looks like you're setting up the ExchangeService object correctly. A couple things to try:
Try passing the full email (a_jain#xyz.com) to WebCredentials
Make sure your the domain you're passing to WebCredentials is correct
Try the WebCredentials constructor that only takes username and password.
Note: I don't think autodiscover will work with O365

Related

Getting 403 error when trying to get Folder items from Office 365 mailbox using ExchangeService

I'm trying to read all Inbox email items from an Office 365 mailbox using ExchangeService.
For that, I:
Created an app in my AzureAD portal.
Given this app all permissions.
Issues this app an access secret to use in my code.
The code works to the point that I sucessfully get a token, but when trying to get the folder items I get an 403 error:
'The request failed. The remote server returned an error: (403)
Forbidden.'
I get this error from my dev and my prod environments so I'm pretty sure it's not a network or port issue.
Here's my code:
var cca = ConfidentialClientApplicationBuilder
.Create("myApplicationId")
.WithClientSecret("myClientSecret")
.WithTenantId("myTenantId")
.Build();
var ewsScopes = new string[] { "https://outlook.office365.com/.default" };
// This is where I get the token
var authResult = await cca.AcquireTokenForClient(ewsScopes).ExecuteAsync();
var ewsClient = new ExchangeService();
ewsClient.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
ewsClient.Credentials = new OAuthCredentials(authResult.AccessToken);
ewsClient.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "my#mail.box");
ewsClient.HttpHeaders.Add("X-AnchorMailbox", "my#mail.box");
// This is where I get the 403 error:
var items = ewsClient.FindItems(
new FolderId(WellKnownFolderName.Inbox, new Mailbox("my#mail.box")),
new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {}
),
new ItemView(15)
);
403 if its coming back from Office365 sounds like they have either disabled EWS on the Mailbox your trying to access or they have limited the clients that are allowed to connect eg https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-control-access-to-ews-in-exchange . You could try testing EWS itself using a user account via the EWSeditor https://github.com/dseph/EwsEditor

MailKit: throws Authentication Failed while calling Authenticate method from the Pop3Client class

I am using MailKit for sending and receiving emails. but when I try to get emails, I get the Authentication Failed error. here is my code:
using MailKit.Net.Pop3;
using MimeKit;
public List<Email> GetEmails()
{
using var emailClient = new Pop3Client();
emailClient.Connect("pop.mail.yahoo.com", 995, true);
emailClient.AuthenticationMechanisms.Remove("XOAUTH2"); //commenting this line won't help.
emailClient.Authenticate("email", "password"); // this line throws 'Authentication Failed' exception.
var emails = new List<Email>();
for (int i = 0; i < 10; i++)
{
var message = emailClient.GetMessage(i);
var emailMessage = new Email
{
Content = message.TextBody,
Subject = message.Subject
};
emails.Add(emailMessage);
}
return emails;
}
Does anyone have any idea?
I know this sounds obvious, but the odds are that you're providing the wrong username and/or password. That's what the error is saying.
You can verify this by looking at the log file:
var emailClient = new Pop3Client(new ProtocolLogger("pop3.log"))
Maybe you can try creating a new Yahoo! Mail account that fails to authenticate just like your real account and give me the username/password for that new account so that I can debug the issue?
Does your username or password contain non-ASCII characters? How about punctuation characters?
If you want me to dig into this, I need to know what the username/password are and what MailKit is sending in case it's sending the wrong strings (pretty sure it's not, but I'll look into it anyway). If you don't give me that info, I can't diagnose the issue.

C# Console Application - Parsing Office 365 Inbox

I was able to succeed via a package I found called EAGetMail. Unfortunately, I realized soon after that they have a token system and this is not a free approach.
There are a couple other choices available, like using Outlook Mail REST API, and MimeKit, but I'm lost on how to achieve my end result because no "start to finish" code is available on either of these references that demonstrates how to parse an Inbox for an account.
I've started to write this with the help of Mimekit, but am not sure if this is the proper way at all.
I must imagine it looks something like:
using (var client = new SmtpClient ())
{
client.Connect("outlook.office365.com", 587);
client.Authenticate("myemail#office365account.com", "mypassword");
var message = MimeMessage.Load(stream);
}
I don't know how to setup the stream mentioned above, and I don't know if it's possible to do this with Mimekit and Office 365.
I'm open to seeing a solution for this in any other approach that's not through EAGetMail. If anyone has a lightweight solution ranging from actual establishing a connection, to pulling messages from the inbox, would be great to see!
I've got it using EWS (Exchange Web Services). Here's my code:
private static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
// The default for the validation callback is to reject the URL.
bool result = false;
Uri redirectionUri = new Uri(redirectionUrl);
// Validate the contents of the redirection URL. In this simple validation
// callback, the redirection URL is considered valid if it is using HTTPS
// to encrypt the authentication credentials.
if (redirectionUri.Scheme == "https")
{
result = true;
}
return result;
}
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);
service.Credentials = new WebCredentials("email#myemail.com", "myPassword");
service.AutodiscoverUrl("email#myemail.com", RedirectionUrlValidationCallback);
//creates an object that will represent the desired mailbox
Mailbox mb = new Mailbox(#"email#myemail.com");
//creates a folder object that will point to inbox folder
FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);
//this will bind the mailbox you're looking for using your service instance
Folder inbox = Folder.Bind(service, fid);
//load items from mailbox inbox folder
if (inbox != null)
{
FindItemsResults<Item> items = inbox.FindItems(new ItemView(100));
foreach (var item in items)
{
item.Load();
Console.WriteLine("Subject: " + item.Subject);
}
}
}

How to send mails using SmtpClient and DefaultNetworkCredentials to a distribution list that only allows authenticated senders?

I'm trying to send automated emails from a C# console application from machines to clients all on the same domain via our internal Exchange 2007 server (using SMTP), but I'm hitting a snag with distribution lists that only allow authenticated senders. Basically the mails I'm sending are getting rejected by Exchange with:
#550 5.7.1 RESOLVER.RST.AuthRequired; authentication required ##rfc822;AuthTESTGroup#example.com
I'm using System.Net.Mail.SmtpClient and setting the Credentials property to System.Net.CredentialCache.DefaultNetworkCredentials, but somewhere along the line, the credentials of the account running this program (me, a valid domain user with a valid mailbox) are not getting passed down to Exchange correctly.
I'm using System.Net.CredentialCache.DefaultNetworkCredentials because I do not want to hard code a username or password (either in the code itself or in any sort of configuration file); I want the process to authenticate with our SMTP server using Windows authentication.
Here is a test program I've been using to reproduce the problem (domain names have been anonomized):
using System;
using System.Net.Mail;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var smtpClient = new SmtpClient
{
Host = "MAIL",
Port = 25,
DeliveryMethod = SmtpDeliveryMethod.Network,
Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
};
var mailMessage = new MailMessage
{
Body = "Testing",
From = new MailAddress(Environment.UserName + "#example.com"),
Subject = "Testing",
Priority = MailPriority.Normal
};
mailMessage.To.Add("AuthTESTGroup#example.com");
smtpClient.Send(mailMessage);
}
}
}
Whenever I run this as myself (again, I'm a valid user on the domain, with an existing mailbox on the Exchange server) I get an undeliverable bounce message from Exchange with the response:
#550 5.7.1 RESOLVER.RST.AuthRequired; authentication required ##rfc822;AuthTESTGroup#example.com
I talked to our Exchange server admin and he saw the following error from the Exchange server's event log:
Account For Which Logon Failed:
Security ID: NULL SID
Account Name:
Account Domain:
Failure Information:
Failure Reason: Unknown user name or bad password.
Status: 0xc000006d
Sub Status: 0xC0000064
Apparently that status code and sub status code translate to:
0xc000006d This is either due to a bad username or authentication information. Usually logged as status code with 0xc0000064 as substatus
0xC0000064 user name does not exist
So again, it's as if somewhere along the line, my Windows credentials are not getting passed down to the Exchange server even though I'm setting the SmtpClient.Credentials to System.Net.CredentialCache.DefaultNetworkCredentials
Any ideas?
Thanks in advance!
you need to pass username, password
here is a code snippet of how I would do it... keep in mind this is a code snippet you need to make the necessary changes to fit your Use Case
MailClient = new SmtpClient();
MailClient.Credentials = new System.Net.NetworkCredential(username, password);
below is another example but uses the server variable.. this maybe what you need to do try and let me know the server for example you can pass as your domain.com
example :
//SmtpClient client = new SmtpClient("smtp.contoso.com");//this would be server
//client.Credentials = CredentialCache.DefaultNetworkCredentials;
public static void CreateBccTestMessage(string server)
{
MailAddress from = new MailAddress("ben#contoso.com", "Ben Miller");
MailAddress to = new MailAddress("jane#contoso.com", "Jane Clayton");
MailMessage message = new MailMessage(from, to);
message.Subject = "Using the SmtpClient class.";
message.Body = #"Using this feature, you can send an e-mail message from an application very easily.";
MailAddress bcc = new MailAddress("manager1#contoso.com");
message.Bcc.Add(bcc);
SmtpClient client = new SmtpClient(server);
client.Credentials = CredentialCache.DefaultNetworkCredentials;
Console.WriteLine("Sending an e-mail message to {0} and {1}.",
to.DisplayName, message.Bcc.ToString());
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateBccTestMessage(): {0}",
ex.ToString());
}
}

How to get Item web client id in Exchange 2007 using EWS Managed API

I have an EmailMessage item saved in Draft folder. I need to open an editing form of it in browser, but cannot found id that is used by web client. In documentation there is such property, but it fails with Microsoft Exchange Server 2007. What is alternative?
Any help is appreciated.
I've found.
ExchangeService service = new ExchangeService();
EmailMessage message = EmailMessage.Bind(new ItemId("someId"));
var alternateId = new AlternateId();
alternateId.UniqueId = message.Id.UniqueId;
alternateId.Mailbox = "somemailbox";
alternateId.Format = IdFormat.EwsId;
var convertedId = service.ConverId(alternateId, Format.OwaId) as AlternateId;
And convertedId.UniqueId is what I need;

Categories

Resources