Использование INDY 10 SMTP с Office365

Я не знаком с компонентом INDY SMTP. Я хочу отправить письмо с помощью INDY и Office 365. Вот хорошая тема, которая мне очень помогла: Что делают свойства безопасности и аутентификации компонента SMTP Indy? Но я не понял, как использовать SASL. Адрес Office365 - smtp.office365.com с портом 587 и TLS. Поэтому я добавил в свою форму SMTP и OpenSSL-IOHandler и настроил свойства. Но у меня не получилось, приложение просто зависает. Мне нужно знать, как использовать SASL с Office365.

Спасибо.


person Timestop    schedule 18.07.2013    source источник
comment
SASL и TLS - это совершенно разные и не связанные между собой вещи. SASL разработан для защиты учетных данных пользователя, которые передаются через соединение. TLS предназначен для шифрования самого соединения, независимо от того, что по нему передается. Так в чем вам на самом деле нужна помощь? Использование TLS для установки сокетного соединения с Office35 или использование SASL для аутентификации с Office365 после установления соединения, или и то, и другое? Пожалуйста, будьте более конкретными.   -  person Remy Lebeau    schedule 19.07.2013
comment
Вы не предоставили фактические настройки, которые вы использовали, или не показали фактический код, который использует TIdSMTP. Таким образом, нет возможности диагностировать вашу проблему.   -  person Remy Lebeau    schedule 19.07.2013
comment
Спасибо за помощь. Да, мне нужна помощь в обоих случаях. Здесь показан простой код SMTP delphi-treff. de / tutorials / netzwerk-und-internet / indy / Мой код выглядит почти так же. Но я не знаю, как правильно настроить TLS и SASL. Для TLS я добавил INDY OpenSSL-IOHandler, связал его с TIdSMTP и установил TLS как параметр SSL и в свойстве UseTLS utUseExplicitTLS. OpenSSL также установлен. Но я не знаю, какие SASL-параметры использует Office365 и как их настроить с помощью Indy. Я выложу код. Кстати. Я новичок и не понимаю, как использовать теги кода ...   -  person Timestop    schedule 19.07.2013
comment
В этом учебном примере не используются TLS или SASL. Что касается вашего кода, вместо того, чтобы пытаться выяснить, какой SASL использовать, просто включите их все (или, по крайней мере, наиболее часто используемые - CRAM-MD5, CRAM-SHA1, NTLM и т. Д.) И позвольте TIdSMTP решить за вас, какой SASL для использования на основе фактических возможностей Office365, он сообщает, когда TIdSMTP подключается к нему (для работы TIdSMTP.UseEHLO должно быть установлено значение True).   -  person Remy Lebeau    schedule 19.07.2013
comment
Когда я вхожу в Office365, используя TIdSMTP и TLS=utUseExplicitTLS на порту 587, он подключается нормально, без зависаний, и единственный протокол SASL, о поддержке которого он сообщает, - это LOGIN (LOGIN небезопасен, но использование TLS компенсирует это). При попытке проверить мои учетные данные происходит кратковременное зависание, но затем он размораживается и выдает ошибку аутентификации, как и ожидалось (поскольку у меня нет учетной записи Office365).   -  person Remy Lebeau    schedule 19.07.2013
comment
На самом деле есть 2 способа использовать LOGIN SASL с TIdSMTP: 1) установить TIdSMTP.AuthType=satDefault и использовать TIdSMTP.Username и TIdSMTP.Password, 2) установить TIdSMTP.AuthType=satSASL, присоединить TIdSASLLogin к коллекции TIdSMTP.SASLMechanisms и прикрепить TIdUserPassProvider к TIdSASLLogin.   -  person Remy Lebeau    schedule 19.07.2013
comment
Я выложил сейчас примеры кода.   -  person Remy Lebeau    schedule 19.07.2013


Ответы (1)


Office365 поддерживает только LOGIN SASL на порту 587 TLS.

Следующий код отлично работает у меня, когда я только что попробовал (все эти настройки также можно настроить во время разработки):

  1. установка для свойства TIdSMTP.AuthType значения satDefault, который использует команду SMTP AUTH LOGIN:

    var
      idSMTP1: TIdSMTP;
    begin
      idSMTP1 := TIdSMTP.Create(nil);
      try
        idSMTP1.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(idSMTP1);
        idSMTP1.UseTLS := utUseExplicitTLS;
        TIdSSLIOHandlerSocketOpenSSL(idSMTP1.IOHandler).SSLOptions.Method := sslvSSLv3;
    
        idSMTP1.Host := 'smtp.office365.com';
        idSMTP1.Port := 587;
    
        idSMTP1.AuthType := satDefault;
        idSMTP1.Username := ...;
        idSMTP1.Password := ...;
    
        try
          idSMTP1.Connect;
          try
            idSMTP1.Authenticate;
          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;
    
  2. установив для свойства TIdSMTP.AuthType значение satSASL и используя TIdSASLLogin, который использует ту же команду SMTP AUTH LOGIN:

    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 := sslvSSLv3;
    
        idSMTP1.Host := 'smtp.office365.com';
        idSMTP1.Port := 587;
    
        idSASLLogin := TIdSASLLogin.Create(idSMTP1);
        idUserPassProvider := TIdUserPassProvider.Create(idSASLLogin);
    
        idSASLLogin.UserPassProvider := idUserPassProvider;
        idUserPassProvider.Username := ...;
        idUserPassProvider.Password := ...;
    
        idSMTP1.AuthType := satSASL;
        idSMTP1.SASLMechanisms.Add.SASL := idSASLLogin;
    
        try
          idSMTP1.Connect;
          try
            idSMTP1.Authenticate;
          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;
    

Обновление: Office365 больше не поддерживает SSL v3, теперь необходимо использовать TLS v1.x:

(idSMTP1.IOHandler).SSLOptions.Method := sslvTLSv1;
person Remy Lebeau    schedule 19.07.2013
comment
Спасибо :) Теперь разобрался. Я забыл PassProvider. Но теперь это работает. Спасибо. Это решит будущие проблемы с другими провайдерами. - person Timestop; 19.07.2013
comment
Привет, @Remy. К сожалению, я получаю следующую ошибку, используя приведенный выше код: EIdOSSLConnectError 'Error connecting with SSL. EOF was observed that violates the protocol' Исключение возникает в строке idSMTP1.Authenticate;. Затем следует это исключение: EIdTLSClientTLSHandShakeFailed 'SSL negotiation failed.' Любая помощь будет принята с благодарностью. - person jamesmstone; 24.03.2016
comment
Для свойства UseTLS должно быть установлено значение utUseExplicitTLS. Это заставляет Authenticate() отправить STARTTLS команду для шифрования соединения перед отправкой учетных данных для аутентификации (обычно для порта 587). Ошибка означает, что сервер принимает команду STARTTLS, но затем разрывает соединение сокета во время квитирования SSL / TLS до его завершения. Серверу, вероятно, не нравится, как вы настроили OpenSSL. Возможно, ему не нравятся выбранные версии протокола или настройки сертификата / проверки. Трудно сказать, не увидев настоящего рукопожатия. - person Remy Lebeau; 24.03.2016
comment
Это правильный ответ, но на момент комментирования (2016-08) требования Office365 изменились. Изменения, необходимые для выполнения этого запуска сейчас, можно найти в ответе на мой вопрос здесь: stackoverflow.com/questions/38740921/ - person Larry Lustig; 04.08.2016