如何解决[EIdSMTPReplyError]身份验证失败?

时间:2020-02-19 07:23:19

标签: delphi

我正在尝试将SMTP与TLS和Office365结合使用。我能够使用Powershell和TLS成功发送电子邮件,但是在下面的示例中,我目前遇到错误:

项目SMTP_SSL_Example.exe引发异常类EIdSMTPReplyError 并显示“验证失败 [JN2P275CA0026.ZAFP275.PROD.OUTLOOK.COM]'

连接成功,但是代码中的身份验证部分失败。以前,我被告知响应来自服务器。如果我使用PowerShell成功收到邮件,这会有什么不同?有什么想法吗?

我正在使用Indy 10.6.2.5366。

更新:另一件套装也出现同样的错误。我只是不明白为什么Powershell允许我发送邮件,但是我不能以编程方式。

procedure TForm28.Method2Click(Sender: TObject);
var
  idSMTP1: TIdSMTP;
  idSASLLogin: TIdSASLLogin;
  idUserPassProvider: TIdUserPassProvider;
begin
  idSMTP1 := TIdSMTP.Create(nil);
  try
    idSMTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idSMTP1);
    idSMTP1.UseTLS := utUseExplicitTLS;
    TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.Method := sslvTLSv1;

    idSMTP1.Host := 'smtp.office365.com';
    idSMTP1.Port := StrToInt(cbPort.Text);

    idSASLLogin := TIdSASLLogin.Create(idSMTP1);
    idUserPassProvider := TIdUserPassProvider.Create(idSASLLogin);

    idSASLLogin.UserPassProvider := idUserPassProvider;
    idUserPassProvider.Username := 'my username';
    idUserPassProvider.Password := 'my passowrd';

    idSMTP1.AuthType := satSASL;
    idSMTP1.SASLMechanisms.Add.SASL := idSASLLogin;

    try
      idSMTP1.Connect;
      try
        idSMTP1.Authenticate;
        SendEmail(idSMTP1);
      finally
        idSMTP1.Disconnect;
      end;
      ShowMessage('OK');
    except
      on E: Exception do
      begin
        ShowMessage(Format('Failed!'#13'[%s] %s', [E.ClassName, E.Message]));
        raise;
      end;
    end;
  finally
    idSMTP1.Free;
  end;
end;

procedure TForm28.Mehod1Click(Sender: TObject);
var
  idSMTP1: TIdSMTP;
begin
  idSMTP1 := TIdSMTP.Create(nil);
  try
    idSMTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idSMTP1);
    idSMTP1.UseTLS := utUseExplicitTLS;
    TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.Method := sslvTLSv1;

    idSMTP1.Host := 'smtp.office365.com';
    idSMTP1.Port := StrToInt(cbPort.Text);

    idSMTP1.AuthType := satDefault;
    idSMTP1.Username := 'my username';
    idSMTP1.Password := 'my password';


    try
      idSMTP1.Connect;
      try
        idSMTP1.Authenticate;
        SendEmail(idSMTP1);
      finally
        idSMTP1.Disconnect;
      end;
      ShowMessage('OK');
    except
      on E: Exception do
      begin
        ShowMessage(Format('Failed!'#13'[%s] %s', [E.ClassName, E.Message]));
        raise;
      end;
    end;
  finally
    idSMTP1.Free;
  end;
end;

1 个答案:

答案 0 :(得分:0)

Office 365将soon require TLS 1.2,但是您的代码强制Indy使用TLS 1.0。 Office 365正式不再支持TLS 1.0或1.1,但是暂时仍接受1.0 / 1.1会话,但是在接下来的几个月中将会有所改变。

因此,至少,您需要更改此内容:

TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.Method := sslvTLSv1;

对此:

TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.Method := sslvTLSv1_2;

或者更好的是,

TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];

话虽这么说,使用TIdSASLLogin作为唯一的SASL机制与使用TIdSMTP.AuthType=satDefault完全相同。它们都向服务器发送相同的AUTH LOGIN命令。而该命令是失败的。但是没有办法确切地知道为什么会这样。 “身份验证失败”过于笼统地显示一条错误消息,并且有很多原因导致该错误在Office 365中发生。也许您使用的用户名/密码错误。也许TIdSMTP在其EHLO命令 1 中由主机名解析的IP地址未在服务器上列入白名单。谁知道。

1:尝试将TIdSMTP.HeloName属性设置为客户端计算机的FQDN,您可以从GetComputerNameEx()获得该属性。