Delphi 在Office365中使用INDY 10 SMTP

Delphi 在Office365中使用INDY 10 SMTP,delphi,smtp,indy,indy10,office365,Delphi,Smtp,Indy,Indy10,Office365,我不熟悉INDY SMTP组件。我想用印地和Office 365发送邮件。这是一个很好的话题,对我帮助很大: 但我没有弄明白如何使用SASL。Office365地址为smtp.Office365.com,端口为587和TLS。因此,我在表单中添加了一个SMTP和一个OpenSSL IOHandler,并设置了属性。但我没有工作,应用程序只是冻结。我需要知道如何在Office365中使用SASL 谢谢。Office365仅支持TLS端口587上的登录SASL 当我刚刚尝试时,以下代码对我来说很好(

我不熟悉INDY SMTP组件。我想用印地和Office 365发送邮件。这是一个很好的话题,对我帮助很大: 但我没有弄明白如何使用SASL。Office365地址为smtp.Office365.com,端口为587和TLS。因此,我在表单中添加了一个SMTP和一个OpenSSL IOHandler,并设置了属性。但我没有工作,应用程序只是冻结。我需要知道如何在Office365中使用SASL


谢谢。

Office365仅支持TLS端口587上的
登录
SASL

当我刚刚尝试时,以下代码对我来说很好(所有这些设置也可以在设计时设置):

  • tidstp.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;
    
    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;
    
  • tidstp.AuthType
    属性设置为
    satsal
    并使用
    tidsallogin
    ,该属性使用相同的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;
    
    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;
    

    SASL和TLS是完全独立和不相关的东西。SASL旨在保护通过连接传输的用户凭据。TLS设计用于加密连接本身,而不管通过它传输什么。那么你到底需要什么帮助呢?使用TLS与Office35建立套接字连接,或在建立连接后使用SASL与Office365进行身份验证,或两者兼而有之?请更具体一些。您没有提供实际使用的设置,也没有显示正在使用
    tidstp
    的实际代码。所以无法诊断您的问题。谢谢您的帮助。是的,两方面我都需要帮助。这里显示了一个简单的SMTP代码,我的代码看起来几乎相同。但我不知道如何正确设置TLS和SASL。对于TLS,我添加了一个INDY OpenSSL IOHandler,将其与TIdSMTP链接,并将TLS设置为SSL选项和“UseTLS”属性utUseExplicitTLS下。还安装了OpenSSL。但我不知道Office365使用哪种SASL选项,以及如何与Indy进行设置。我会发布一些代码。顺便说一句,我是新来的,不知道如何使用代码标签…那个教程示例没有使用TLS或SASL。至于您的代码,与其试图找出要使用哪种SASL,不如全部启用它们(或者至少启用最常用的SASL-CRAM-MD5、CRAM-SHA1、NTLM等),然后让
    tidstp
    根据连接到它时报告的Office365的实际功能来决定使用哪种SASL(您必须将
    tidstp.UseEHLO
    设置为True才能工作)。当我在端口587上使用
    tidstp
    TLS=utUseExplicitTLS
    登录到Office365时,它连接正常,不会冻结,并且它报告支持的唯一SASL是
    login
    LOGIN
    不安全,但使用TLS可以弥补这一点)。它尝试验证我的凭据时会暂时冻结,但随后会解冻并抛出身份验证错误,正如预期的那样(因为我没有Office365帐户)。谢谢:)现在我明白了。我忘记了PassProvider。但是现在它起作用了。谢谢。这将解决其他提供商将来的问题。嗨@Remy,很不幸,使用上面的代码我收到了以下错误:EIdOSSLConnectError
    “连接SSL时出错。观察到EOF违反了协议”
    上引发了异常idSMTP1.Authenticate;
    行。然后出现此异常:eidtlsclientlshandshakefailed
    SSL协商失败。
    非常感谢您的帮助。您必须将
    UseTLS
    属性设置为
    utusexplicittls
    。这会导致
    Authenticate()
    发送
    STARTTLS
    命令以在发送身份验证凭据之前加密连接(端口587通用)。此错误表示服务器正在接受
    STARTTLS
    命令,但随后在SSL/TLS握手过程中断开套接字连接,直到该命令完成。服务器可能不喜欢您配置OpenSSL的方式。可能不喜欢协议版本已选择,或证书/验证设置。如果看不到实际握手,很难说。此答案是正确的,但在发表评论时(2016-08),Office365已更改了要求。现在进行此运行所需的修改可以在我的问题的答案中找到: