Как решить проблему [EIdSMTPReplyError] Аутентификация не удалась? - PullRequest
0 голосов
/ 19 февраля 2020

Я пытаюсь использовать 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 голосов
/ 19 февраля 2020

Office 365 скоро потребует 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 на сервер. И эта команда - то, что терпит неудачу. Но невозможно точно знать, почему это происходит. «Аутентификация неудачна» - слишком общее c сообщение об ошибке, и есть много причин, почему эта ошибка возникает в Office 365. Возможно, вы используете неправильное имя пользователя / пароль. Возможно, IP-адрес, разрешенный по имени хоста, отправляемого TIdSMTP в его команде EHLO 1 , не занесен в белый список на сервере. Кто знает.

1: попробуйте задать для свойства TIdSMTP.HeloName полное доменное имя для своего клиентского компьютера, которое можно получить из GetComputerNameEx().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...