12

I'm trying to set up some code to send email via Office 365's authenticated SMTP service:

var _mailServer = new SmtpClient();
_mailServer.UseDefaultCredentials = false;
_mailServer.Credentials = new NetworkCredential("test.user@mydomain.com", "password");
_mailServer.Host = "smtp.office365.com";
_mailServer.TargetName = "STARTTLS/smtp.office365.com"; // same behaviour if this lien is removed
_mailServer.Port = 587;
_mailServer.EnableSsl = true;

var eml = new MailMessage();
eml.Sender = new MailAddress("test.user@mydomain.com");
eml.From = eml.Sender;
eml.to = new MailAddress("test.recipient@anotherdomain.com");
eml.Subject = "Test message";
eml.Body = "Test message body";

_mailServer.Send(eml);

This doesn't appear to be working, and I'm seeing an exception:

The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP; Client was not authenticated to send anonymous mail during MAIL FROM
at System.Net.Mail.MailCommand.Send(SmtpConnection conn, Byte[] command, String from)
at System.Net.Mail.SmtpTransport.SendMail(MailAddress sender, MailAddressCollection recipients, String deliveryNotify, SmtpFailedRecipientException& exception)
at System.Net.Mail.SmtpClient.Send(MailMessage message)

I've tried enabling network tracing and it appears that secure communications are established (for example, I see a line in the log for the "STARTTLS" command, and later there's a line in the log "Remote certificate was verified as valid by the user.", and the following Send() and Receive() data is not readable as plain text, and doesn't appear to contain any TLS/SSH panics)

I can use the very same email address and password to log on to http://portal.office.com/ and use the Outlook email web mail to send and read email, so what might be causing the authentication to fail when sending email programmatically?

Is there any way to additionally debug the encrypted stream?

Rowland Shaw
  • 37,700
  • 14
  • 97
  • 166
  • is the address specified in `eml.From = eml.Sender;` the same as the email address of the account you are connecting to? If you change the email address specified in the `From` field to be that of the account, does the email send successfully? If so, it is probably the case that the SMTP is configured to fail to send emails which look like they come from a different account. – user1666620 Mar 02 '16 at 15:48
  • 2
    It still fails if only the `From` is set, and no `Sender` is specified. In all cases, the `From` matches the `NetworkCredentials` – Rowland Shaw Mar 02 '16 at 15:54
  • I'm out of ideas in that case, since otherwise your code looks fine. If you do find a solution, can you post it here? Am interested in finding out what the cause is. – user1666620 Mar 02 '16 at 16:35
  • `Client was not authenticated to send anonymous mail during MAIL FROM` says that you are trying to send anonymous mail, which means it does not recognize your `From` address. – jstedfast Mar 02 '16 at 17:29
  • @jstedfast why would it not recognise the sender, when I can log in to Office 365 with it? – Rowland Shaw Mar 02 '16 at 17:29
  • Where are you getting the `From` address from? User input? An XML file? Hard-coded? Is it possible that the `From` address is mis-spelled or contains extra characters (that maybe aren't visible)? – jstedfast Mar 02 '16 at 17:33
  • Does your password contain non-ASCII characters? Looks like office365.com stores password encoded in ISO-8859-1 but I think SmtpClient sends passwords as UTF-8, so that would cause things to fail to authenticate... which I would expect would mean it wouldn't even get to the MAIL FROM command, but perhaps it tries to send anyway? – jstedfast Mar 02 '16 at 17:40
  • @jstedfast For the moment, I'm trying with a hard coded email and password, neither use any non-ASCII characters, and copy/paste and log-in correctly to portal.office.com (per my question) – Rowland Shaw Mar 02 '16 at 19:53
  • Try disabling STARTTLS. Office365.com's SMTP server may be broken in that sending EHLO after the STARTLS may confuse the server (it's happened before). – jstedfast Mar 02 '16 at 19:55
  • Per question, behaviour is the same without the `Target` set to initiate TLS, which in turn is required to send via SMTP through Office 365 – Rowland Shaw Mar 02 '16 at 20:01
  • No, I mean don't set `UseSsl = true`. Port 587 doesn't require SSL, it's just an extra layer of protection for the client. – jstedfast Mar 02 '16 at 20:40
  • This may be helpful: http://stackoverflow.com/questions/29648391/exception-using-default-smtp-credentials-on-office365-client-was-not-authentic – jstedfast Mar 02 '16 at 21:52
  • Another idea might be that you need to use a domain specifier in your NetworkCredentials, although that would depend on the SASL AUTH mechanism being something like NTLM and not PLAIN or LOGIN. – jstedfast Mar 03 '16 at 15:14
  • @JohnieKarr Still not able to send authenticated mail via Office 365 - for the moment we're using a secondary (non O365) SMTP server. – Rowland Shaw May 20 '16 at 15:43
  • We were actually just able to resolve this. We had set our mailbox up as a "shared" account, which wouldn't work. When my network admin changed the account type to "regular" then it started working properly. – Johnie Karr May 20 '16 at 18:47
  • @Abjo I've still been unable to resolve this, and for the time being, we've taken the approach to use an unauthenticated connection for our internal operations – Rowland Shaw Oct 11 '17 at 07:50
  • did you get any solution? – Kiquenet May 09 '18 at 08:26
  • @pixelbyaj In Octuber 11th you indicated this was still a problem for you. Has it been resolved yet (May 09th, 2018)? I'm facing the same problem – Kiquenet May 09 '18 at 08:59
  • One thing we did was to add the server, which sends the request to the SMTP to the allowed list in the SMTP. – Thanigainathan Dec 08 '18 at 00:38

10 Answers10

6

In my case after I tried all this suggestion without luck, I contacted Microsoft support, and their suggestion was to simply change the password.

This fixed my issue.

Note that the password wasn't expired, because I logged on office365 with success, however the reset solved the issue.

Lesson learned: don't trust the Office 365 password expiration date, in my case the password would be expired after 1-2 months, but it wasn't working. This leaded me to investigate in my code and only after a lot of time I realized that the problem was in the Office365 password that was "corrupted" or "prematurely expired".

Don't forget every 3 months to "refresh" the password.

Matteo Conta
  • 1,423
  • 13
  • 17
5

To aid in debugging, try temporarily switching to MailKit and using a code snippet such as the following:

using System;

using MailKit.Net.Smtp;
using MailKit.Security;
using MailKit;
using MimeKit;

namespace TestClient {
    class Program
    {
        public static void Main (string[] args)
        {
            var message = new MimeMessage ();
            message.From.Add (new MailboxAddress ("", "test.user@mydomain.com"));
            message.To.Add (new MailboxAddress ("", "test.recipient@anotherdomain.com"));
            message.Subject = "Test message";

            message.Body = new TextPart ("plain") { Text = "This is the message body." };

            using (var client = new SmtpClient (new ProtocolLogger ("smtp.log"))) {
                client.Connect ("smtp.office365.com", 587, SecureSocketOptions.StartTls);

                client.Authenticate ("test.user@mydomain.com", "password");

                client.Send (message);
                client.Disconnect (true);
            }
        }
    }
}

This will log the entire transaction to a file called "smtp.log" which you can then read through and see where things might be going wrong.

Note that smtp.log will likely contain an AUTH LOGIN command followed by a few commands that are base64 encoded (these are your user/pass), so if you share the log, be sure to scrub those lines.

I would expect this to have the same error as you are seeing with System.Net.Mail, but it will help you see what is going on.

Assuming it fails (and I expect it will), try changing to SecureSocketOptions.None and/or try commenting out the Authenticate().

See how that changes the error you are seeing.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
3

Be sure you're using the actual office365 email address for the account. You can find it by clicking on the profile button in Outlook365. I wrestled with authentication until I realized the email address I was trying to use for authentication wasn't the actual mailbox email account. The actual account email may have the form of: account@company.onmicrosoft.com.

Derek Wade
  • 697
  • 8
  • 11
2

We got ours working by converting the mailboxes (from address) from "shared" to "regular". Before this change, my application quit sending email when we migrated from Gmail to Office 365. No other code changes were required, besides setting the host to smtp.office365.com.

Johnie Karr
  • 2,744
  • 2
  • 35
  • 44
1

Please check below code I have tested to send email using Exchange Online:

        MailMessage msg = new MailMessage();
        msg.To.Add(new MailAddress("YourEmail@hotmail.com", "XXXX"));
        msg.From = new MailAddress("XXX@msdnofficedev.onmicrosoft.com", "XXX");
        msg.Subject = "This is a Test Mail";
        msg.Body = "This is a test message using Exchange OnLine";
        msg.IsBodyHtml = true;

        SmtpClient client = new SmtpClient();
        client.UseDefaultCredentials = false;
        client.Credentials = new System.Net.NetworkCredential("XXX@msdnofficedev.onmicrosoft.com", "YourPassword");
        client.Port = 587; // You can use Port 25 if 587 is blocked
        client.Host = "smtp.office365.com";
        client.DeliveryMethod = SmtpDeliveryMethod.Network;
        client.EnableSsl = true;
        try
        {
            client.Send(msg);

        }
        catch (Exception ex)
        {

        }

enter image description here Port (587) was defined for message submission. Although port 587 doesn't mandate requiring STARTTLS, the use of port 587 became popular around the same time as the realisation that SSL/TLS encryption of communications between clients and servers was an important security and privacy issue.

Nan Yu
  • 26,101
  • 9
  • 68
  • 148
  • 1
    This code is not working for me - which implies it's something to do with the credentials, which confuses me, as I can log on at http://portal.office.com with the the same credentials with no problem. Does something need to be enabled on the mailbox to allow SMTP mail? – Rowland Shaw Mar 03 '16 at 09:31
1

In my case my problem was not related to the code but something to do with the Exchange mailbox. Not sure why but this solved my problem:

  • Go to the exchange settings for that user's mailbox and access Mail Delegation
  • Under Send As, remove NT AUTHORITY\SELF and then add the user's account.

This gives permissions to the user to send emails on behalf of himself. In theory NT AUTHORITY\SELF should be doing the same thing but for some reason that did not work.

Source: http://edudotnet.blogspot.com.mt/2014/02/smtp-microsoft-office-365-net-smtp.html

Matt R
  • 106
  • 1
  • 2
1

I got this same error while testing, using my own domain email account during development. The issue for me seemed related to the MFA (Multi Factor Authentication) that's enabled on my account. Switching to an account without MFA resolved the issue.

Carl Heinrich Hancke
  • 2,660
  • 1
  • 30
  • 35
1

I had this issue since someone had enabled Security defaults in Azure. This disables SMTP/Basic authentication. It's clearly stated in the documentation, but it's not evident by the error message, and you have to have access to the account to find out.

https://learn.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults

It's possible to enable it per account. https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission

0

You need change the credentials function. Here is the substitution you need to make:

change

-*_mailServer.Credentials = new NetworkCredential("test.user@mydomain.com", "password");*

for this

-*_mailServer.Credentials = new NetworkCredential("test.user@mydomain.com", "password", "domain");*
Nick
  • 3,454
  • 6
  • 33
  • 56
Calm
  • 1
0

In my case, password was expired.I just reset password and its started working again

lazydeveloper
  • 891
  • 10
  • 20