【问题标题】:Using INDY 10 SMTP with Office365将 INDY 10 SMTP 与 Office365 一起使用
【发布时间】:2013-07-18 01:11:59
【问题描述】:

我不熟悉 INDY SMTP 组件。我想用 INDY 和 Office 365 发送邮件。这是一个很好的话题,对我有很大帮助:What do the SMTP Indy component security and authentication properties do? 但是我没有弄清楚如何使用SASL。 Office365 地址是 smtp.office365.com,端口为 587 和 TLS。所以我在表单中添加了一个 SMTP 和一个 OpenSSL-IOHandler 并设置了属性。但我没有工作,应用程序只是冻结。我需要知道如何在 Office365 中使用 SASL。

谢谢。

【问题讨论】:

  • SASL 和 TLS 是完全独立且不相关的东西。 SASL 旨在保护通过连接传输的用户凭据。 TLS 旨在加密连接本身,无论通过它传输什么。那么你真正需要帮助的是什么?使用 TLS 建立到 Office35 的套接字连接,还是在建立连接后使用 SASL 对 Office365 进行身份验证,或者两者兼而有之?请更具体。
  • 您没有提供您使用的实际设置,或显示使用TIdSMTP 的实际代码。所以没有办法诊断你的问题。
  • 感谢您的帮助。是的,我在这两个方面都需要帮助。此处显示了一个简单的 SMTP 代码 delphi-treff.de/tutorials/netzwerk-und-internet/indy/… 我的代码看起来几乎相同。但我不知道如何正确设置 TLS 和 SASL。对于 TLS,我添加了一个 INDY OpenSSL-IOHandler,将其与 TIdSMTP 链接并将 TLS 设置为 SSL 选项,并在“UseTLS”属性 utUseExplicitTLS 下。还安装了 OpenSSL。但我不知道 Office365 使用了哪些 SASL-Options 以及如何使用 Indy 进行设置。我会发布一些代码。顺便提一句。我是新手,不明白如何使用代码标签...
  • 该教程示例未使用 TLS 或 SASL。至于你的代码,不要试图弄清楚要使用哪个 SASL,只需启用它们(或至少是最常用的 - CRAM-MD5、CRAM-SHA1、NTLM 等)并让TIdSMTP 为你决定当TIdSMTP 连接到它时,根据Office365 报告的实际功能使用哪个SASL(您必须将TIdSMTP.UseEHLO 设置为True 才能工作)。
  • 当我在端口 587 上使用 TIdSMTPTLS=utUseExplicitTLS 登录 Office365 时,它可以正常连接而不会冻结,并且它报告支持的唯一 SASL 是 LOGIN (LOGIN 是不安全,但 TLS 的使用弥补了这一点)。在尝试验证我的凭据时出现了短暂的冻结,但随后它解冻并引发了身份验证错误,正如预期的那样(因为我没有 Office365 帐户)。

标签: delphi smtp indy indy10 office365


【解决方案1】:

Office365 仅支持 TLS 端口 587 上的LOGIN SASL。

以下代码在我刚尝试时运行良好(所有这些设置也可以在设计时设置):

  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;

【讨论】:

  • 谢谢 :) 现在我想通了。我忘记了 PassProvider。但现在它起作用了。谢谢。这将解决未来与其他提供商的问题。
  • 嗨@Remy 不幸的是,我在使用上面的代码时遇到了以下错误:EIdOSSLConnectError 'Error connecting with SSL. EOF was observed that violates the protocol'idSMTP1.Authenticate; 行上引发了异常。然后是这个异常:EIdTLSClientTLSHandShakeFailed 'SSL negotiation failed.' 任何帮助将不胜感激。
  • 您必须将UseTLS 属性设置为utUseExplicitTLS。这会导致Authenticate() 在发送身份验证凭据之前发送STARTTLS 命令来加密连接(端口587 常见)。该错误意味着服务器正在接受STARTTLS 命令,但是在完成之前的 SSL/TLS 握手期间断开了套接字连接。服务器可能不喜欢您配置 OpenSSL 的方式。也许它不喜欢选择的协议版本或证书/验证设置。很难说没有看到实际的握手。
  • 这个答案是正确的,但在发表评论时(2016-08)Office365 已经改变了要求。现在运行所需的修改可以在我的问题的答案中找到:stackoverflow.com/questions/38740921/…
猜你喜欢
  • 2013-09-03
  • 2016-10-15
  • 2023-03-04
  • 2016-12-09
  • 1970-01-01
  • 2018-09-24
  • 2014-09-16
  • 1970-01-01
  • 2017-04-26
相关资源
最近更新 更多