当前位置: 首页 > 知识库问答 >
问题:

使用Rust lettre库从Exchange SMTP获取“客户端未通过身份验证以在邮件发送期间发送匿名邮件”错误

谭思博
2023-03-14

我正在编写一个Rust应用程序,它将通过启用了SMTP功能的Exchange服务器发送电子邮件。根据微软的网页,需要的设置是:

  • 服务器地址smtp.office365.com
  • 端口587
  • 已启用StartTLS
  • 邮件帐户登录凭据

网络邮件服务的POP/IMAP设置证实了这一点。

这是我的代码(带有一些审查):

extern crate lettre;

use self::lettre::email::EmailBuilder;
use self::lettre::transport::smtp::{SecurityLevel, SmtpTransportBuilder, SUBMISSION_PORT};
use self::lettre::transport::smtp::authentication::Mechanism;
use self::lettre::transport::EmailTransport;

pub fn send_mail() {
    let email = EmailBuilder::new()
        .from("my email")
        .to("destination email")
        .body("testing")
        .subject("testing")
        .build()
        .unwrap();

    // Connect to SMTP server
    let mut transport = SmtpTransportBuilder::new(("smtp.office365.com", SUBMISSION_PORT))
        .expect("Failed to create email transport")
        .encrypt()
        .smtp_utf8(true)
        .credentials("my email", "my password")
        .authentication_mechanism(Mechanism::Login)
        .build();
    println!("Mail transport built");

    println!("{:?}", transport.send(email.clone()));
}

当我编译和运行代码时,它给了我这个错误:

错误(永久(响应{代码:代码{严重性:PermanentNegativeCompletion,类别:未指定3,详细信息:0},消息:[“5.7.57 SMTP;客户端未通过身份验证,无法在来自[SYXPR01CA0106.ausprd01.prod.outlook.com]的邮件发送过程中发送匿名邮件))

为什么会发生这种情况?

我在研究中遇到的最接近的是 GitHub 上与不支持登录身份验证机制(Office 365 使用的)的 lettre 库有关的问题;但是,代码库已更新为支持登录,我直接从 GitHub 使用主分支,因此理论上我的应用程序应该支持登录机制。

编辑:忘记提到我尝试对服务器进行EHLO,但它返回了(客户端:(连接已关闭))错误。

共有1个答案

燕光熙
2023-03-14

我使用telnet和openssl尝试直接连接到SMTP服务器,在那里我发现AUTH LOGIN需要3个命令;一个发送AUTH LOGIN代码,一个发送用户名,另一个发送密码。我发现lettre库将其所有AUTH命令实现为单个命令,因此这不适用于服务器。我下载了库的源代码,更改了send函数以执行三个单独的命令,重新编译了代码,一切都很好:)

我对字母代码的补充:

if (accepted_mechanisms[0] == Mechanism::Login) &&
            (accepted_mechanisms.capacity() == 1) {
            try_smtp!(self.client.command("AUTH LOGIN"), self);
            try_smtp!(self.client.command(base64::encode_config(
                                            &username.as_bytes(),
                                            base64::STANDARD).as_str()), self);
            try_smtp!(self.client.command(base64::encode_config(
                                                        &password.as_bytes(),
                                                        base64::STANDARD).as_str()), self);
 类似资料: