使用c# SmtpClient无法从Office 365发送电子邮件

3
尝试使用SmtpClient从我的WinForms应用程序中发送电子邮件。根据这篇MS article,应该可以工作。我在许多论坛等地方搜索了很久,但没有找到任何解决方案。错误消息似乎表明客户端未经身份验证。密码是正确的,我已经使用此用户登录并输入密码,一切正常。2FA已启用,但它不会妨碍,对吧?
我已经检查了以下事项:
  1. 启用SSL
  2. 发件人和收件人电子邮件相同
  3. 端口587
  4. 我在Outlook中有此帐户,并且可以正常发送
  5. 防火墙未阻止此端口。我有其他代码使用完全相同的代码与非O365主机一起使用,它可以正常工作
代码
            var userName = "user@domain.onmicrosoft.com";
            var password = "password";
            var msg = new MailMessage();
            msg.To.Add(new MailAddress("user@gmail.com"));
            msg.From = new MailAddress(userName);
            msg.Subject = "Test Office 365 Account";
            msg.Body = "Testing email using Office 365 account.";
            msg.IsBodyHtml = true;

            var client = new SmtpClient{
                Host = "smtp.office365.com",
                Credentials = new System.Net.NetworkCredential(userName, password),
                Port = 587,
                DeliveryMethod = SmtpDeliveryMethod.Network,
                EnableSsl = true
            };

            client.Send(msg);

异常

  • SMTP服务器需要安全连接或客户端未经身份验证。服务器响应为:5.7.57 SMTP;客户端未经身份验证发送匿名邮件的MAIL FROM。

邮件工具包实现(vasily.sib的建议)

var message = new MimeMessage();
        message.From.Add(new MailboxAddress("Test User", "user@domain.onmicrosoft.com"));
        message.To.Add(new MailboxAddress("Gmail User", "testuser@gmail.com"));
        message.Subject = "test";

        message.Body = new TextPart("plain")
        {
            Text = @"test"
        };

        var client = new SmtpClient(new ProtocolLogger("imap.log"));


        // For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
        client.ServerCertificateValidationCallback = (s, c, h, e) => true;

        client.Connect("smtp.office365.com", 587, SecureSocketOptions.Auto); //this is fine and it connects

        var clientAuthenticationMechanisms = client.AuthenticationMechanisms;
        client.AuthenticationMechanisms.Remove("XOAUTH2");
        // Note: only needed if the SMTP server requires authentication
        client.Authenticate("user@domain.onmicrosoft.com", "password"); // this is where it fails with Authentication Failure

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

邮件套件日志输出

Connected to smtp://smtp.office365.com:587/?starttls=when-available
S: 220 SYCP282CA0015.outlook.office365.com Microsoft ESMTP MAIL Service ready at Mon, 25 Nov 2019 04:49:36 +0000
C: EHLO [192.168.2.50]
S: 250-SYCP282CA0015.outlook.office365.com Hello [58.6.92.82]
S: 250-SIZE 157286400
S: 250-PIPELINING
S: 250-DSN
S: 250-ENHANCEDSTATUSCODES
S: 250-STARTTLS
S: 250-8BITMIME
S: 250-BINARYMIME
S: 250-CHUNKING
S: 250 SMTPUTF8
C: STARTTLS
S: 220 2.0.0 SMTP server ready
C: EHLO [192.168.2.50]
S: 250-SYCP282CA0015.outlook.office365.com Hello [58.6.92.82]
S: 250-SIZE 157286400
S: 250-PIPELINING
S: 250-DSN
S: 250-ENHANCEDSTATUSCODES
S: 250-AUTH LOGIN XOAUTH2
S: 250-8BITMIME
S: 250-BINARYMIME
S: 250-CHUNKING
S: 250 SMTPUTF8
C: AUTH LOGIN
REMOVED BASE64 DATA (password, login)
S: 535 5.7.3 Authentication unsuccessful [SYCP282CA0015.AUSP282.PROD.OUTLOOK.COM]

微软不建议使用System.Net.Mail.SmtpClient(请参阅备注部分)。建议改用MailKit。 - vasily.sib
@vasily.sib ...我试过了,但它不起作用。无法验证身份...我再次尝试了电子邮件和密码,它们可以正常工作,但在代码中它无法验证身份...是2FA阻止了它吗? - kurasa
你的代码是否在代理服务器下运行,例如公司网络内部? - RICKY KUMAR
@RICKYKUMAR 不行。当我使用MailKit运行它时,我可以成功连接到端口587上的“smtp.office365.com”,但是当我尝试进行身份验证时失败了...我唯一能想到的就是用户名和密码,但它们都没问题,因为我可以使用它们登录到portal.office.com并在那里查看收件箱。 - kurasa
2个回答

4

我今天也遇到同样的问题。 Office365还需要TLS连接。 因此,您应该在代码中添加以下代码

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

我的情况下不需要Expect100Continue。然而,Tls12解决了我的问题。 - 456q

4

问题已解决。原因是2FA阻止了它的发生。关闭2FA后,问题得以解决。


4
无需关闭应用程序,您可以为该应用程序配置一个应用密码。请参阅 https://support.microsoft.com/zh-cn/help/12409/microsoft-account-app-passwords-and-two-step-verification#:~:text=前往“安全基础知识”,选择“应用密码”,然后按照说明进行操作即可生成并获取应用密码。 - Rkand

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