尝试通过Office 365发送电子邮件时出现SMTP 5.7.57错误

12

我正在尝试设置一些代码,通过Office 365的经过身份验证的SMTP服务发送电子邮件:

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);

这似乎无法正常工作,我看到了一个异常:

SMTP服务器需要安全连接或客户端未通过身份验证。 服务器响应是:5.7.57 SMTP; 在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)

我已尝试启用网络跟踪,看起来已经建立了安全通信(例如,在日志中我可以看到“STARTTLS”命令的一行,稍后在日志中有一行“远程证书由用户验证为有效。”,以下的Send()Receive()数据不可读作明文,并且似乎没有包含任何TLS / SSH恐慌)

我可以使用完全相同的电子邮件地址和密码登录http://portal.office.com/并使用Outlook电子邮件Web邮件发送和阅读邮件,那么在以编程方式发送电子邮件时可能会导致身份验证失败?

是否有任何方法可以对加密流进行额外调试?


eml.From = eml.Sender;中指定的地址是否与您正在连接的帐户的电子邮件地址相同?如果将From字段中指定的电子邮件地址更改为帐户的地址,邮件是否能成功发送?如果是这样,那么很可能是SMTP配置为无法发送看起来来自不同帐户的电子邮件。 - user1666620
2
如果只设置了“From”,而没有指定“Sender”,它仍然会失败。在所有情况下,“From”都与“NetworkCredentials”匹配。 - Rowland Shaw
尝试禁用STARTTLS。Office365.com的SMTP服务器可能存在问题,发送STARTLS后发送EHLO可能会使服务器混乱(这种情况以前发生过)。 - jstedfast
我们实际上已经解决了这个问题。我们将我们的邮箱设置为“共享”帐户,这是不起作用的。当我的网络管理员将帐户类型更改为“常规”时,它就开始正常工作了。 - Johnie Karr
@Abjo,我仍然无法解决这个问题,目前我们采取的方法是在内部操作中使用未经身份验证的连接。 - Rowland Shaw
显示剩余14条评论
10个回答

6
为了方便调试,可以暂时切换到MailKit,并使用以下代码片段:
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);
            }
        }
    }
}

这将把整个事务记录到一个名为“smtp.log”的文件中,您可以通过它来查看哪里可能出了问题。
请注意,smtp.log可能包含一个AUTH LOGIN命令,后面跟着一些Base64编码的命令(这些是您的用户/密码),因此如果您分享日志,请确保清除这些行。
我希望这会产生与System.Net.Mail相同的错误,但它将帮助您了解正在发生什么。
假设失败了(我认为会),尝试更改为SecureSocketOptions.None和/或尝试注释Authenticate()。
看看这如何改变您正在看到的错误。

我的asp.net C#网络应用程序无法识别MimeMessage()方法或'using MimeKit;'。 - Dieter
你需要先添加MimeKit/MailKit NuGet包的引用。 - jstedfast
您也可以将Aspose用作带有日志记录的邮件客户端:https://docs.aspose.com/email/net/smtpclient-activity-logging/它的结构更类似于Dotnet Mail代码。 - undefined

6
在我的情况下,我尝试了所有这些建议但都没有成功。于是我联系了微软支持,他们建议我简单地更改密码。
这解决了我的问题。
请注意,密码并没有过期,因为我已经成功地登录了office365,但是重置后问题得到了解决。
教训是:不要相信Office 365密码过期日期。在我的情况下,密码应该在1-2个月内过期,但它并不能正常工作。这导致我检查代码,花费了很多时间才意识到问题在于Office365密码被“损坏”或“过早失效”。
别忘了每3个月“刷新”一次密码。

3

确保您使用的是实际的office365电子邮件帐户地址。您可以通过在Outlook365中单击个人资料按钮来找到它。我曾经为认证而苦苦挣扎,直到意识到我尝试用于认证的电子邮件地址并不是实际的邮箱电子邮件帐户。实际帐户电子邮件地址可能具有以下形式:account@company.onmicrosoft.com。


2

我们通过将邮箱(发件人地址)从“共享”转换为“常规”使其正常工作。在此更改之前,当我们从Gmail迁移到Office 365时,我的应用程序停止发送电子邮件。除了将主机设置为smtp.office365.com之外,不需要进行任何其他代码更改。


这对我也起作用了。不确定为什么会有所不同。 - William
这也是我的问题!谢谢你分享。 - Daniel Congrove

1
请查看我测试过的以下代码,用于使用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)
        {

        }

在这里输入图像描述 端口(587)被定义为邮件提交。尽管端口587不强制要求需要STARTTLS,但是在意识到客户端和服务器之间的通信采用SSL/TLS加密是重要的安全和隐私问题的同时,使用端口587变得流行起来。


1
这段代码对我来说无法工作 - 这意味着它与凭据有关,这让我感到困惑,因为我可以使用相同的凭据在http://portal.office.com上登录而没有任何问题。是否需要启用邮箱上的某些内容以允许SMTP邮件? - Rowland Shaw

1
在测试期间,我使用自己的域名电子邮件帐户时遇到了相同的错误。对我来说,问题似乎与启用了MFA(多因素身份验证)的帐户有关。切换到没有MFA的帐户解决了这个问题。

1
在我的情况下,我的问题与代码无关,但与Exchange邮箱有关。不确定为什么,但这解决了我的问题:
转到该用户邮箱的Exchange设置并访问邮件委派 在发送者下,删除NT AUTHORITY\SELF,然后添加用户帐户。
这样,用户就可以代表自己发送电子邮件。理论上,NT AUTHORITY\SELF应该执行相同的操作,但由于某种原因,这没有起作用。
来源:http://edudotnet.blogspot.com.mt/2014/02/smtp-microsoft-office-365-net-smtp.html

我喜欢这个解决方案,但不确定我们是否可以为整个组织实施。 - Aamir

1

0

在我的情况下,密码已过期。我只是重置了密码,然后它又开始正常工作了。


0
你需要更改凭据函数。这是你需要进行的替换:
更改
-*_mailServer.Credentials = new NetworkCredential("test.user@mydomain.com", "password");*

对于这个

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接