简体   繁体   English

将INDY 10与Exchange SMTP服务器一起使用

[英]Using INDY 10 with Exchange SMTP-Server

From a previous question here I learned how to use INDY SMTP (TIdSMTP) to send mails with an Office 365 account. 这里的上一个问题中我学习了如何使用INDY SMTP(TIdSMTP)通过Office 365帐户发送邮件。 I also figured it out for many others and it works for nearly any common e-mail provider out there. 我还为许多其他人弄清楚了它,并且它几乎可以用于任何常见的电子邮件提供商。 But I can't figure out how to use it with my local Exchange Server. 但是我不知道如何在本地Exchange Server中使用它。 Some time ago there were SASL-NTLM components shipped with indy, but it seems they have been removed. 不久前indy随附了SASL-NTLM组件,但似乎已将其删除。 I need NTLM to connect to a local Exchange Server. 我需要NTLM才能连接到本地Exchange Server。 But I can't figure out how to do this without NTLM. 但是我不知道没有NTLM怎么办。

I have recently struggled with Indy and my Exchange server as well. 我最近在Indy和我的Exchange服务器上也很挣扎。 The SaslNtlm component is not in the version of Indy10 shipped with Delphi XE5. SaslNtlm组件不是Delphi XE5随附的Indy10版本。 It is not even in the source files of the Indy Protocols folder. 它甚至不在Indy Protocols文件夹的源文件中。

Fortunately a lot of the stuff required to do NTLM authentication with the SMTP client is available. 幸运的是,可以使用SMTP客户端进行NTLM身份验证所需的很多东西。 There is a unit called IdAuthenticationSSPI which implements the entire NTLM exchange. 有一个称为IdAuthenticationSSPI的单元,可以实现整个NTLM交换。 All that was left to do was to implement a custom descendant from TIdSASL which interacts with the TIndySSPINTLMClient object. 剩下要做的就是实现TIdSASL的自定义子孙,该子孙与TIndySSPINTLMClient对象进行交互。

  TSaslNtlm = class(TIdSASL)
  public
    constructor Create(AOwner: TComponent);
    destructor Destroy; override;

    function StartAuthenticate(const AChallenge, AHost, AProtocolName : string): string; override;
    function ContinueAuthenticate(const ALastResponse, AHost, AProtocolName : string): string; override;
    function IsReadyToStart: Boolean; override;

    class function ServiceName: TIdSASLServiceName; override;

  private
    FSSPIClient: TIndySSPINTLMClient;
  end;

The implementation of the class is as follows: 该类的实现如下:

constructor TSaslNtlm.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSSPIClient := TIndySSPINTLMClient.Create;
end;

destructor TSaslNtlm.Destroy;
begin
  FSSPIClient.Free;
  inherited;
end;

function TSaslNtlm.StartAuthenticate(const AChallenge, AHost,
                                     AProtocolName: string): string;
begin
  FSSPIClient.SetCredentials(AHost, '', '');
  Result := BytesToStringRaw(FSSPIClient.InitAndBuildType1Message);
end;

function TSaslNtlm.ContinueAuthenticate(const ALastResponse, AHost,
                                        AProtocolName: string): string;
var LastMsg: TIdBytes;
begin
  LastMsg := ToBytes(ALastResponse, Indy8BitEncoding
                     {$IFDEF STRING_IS_ANSI}, Indy8BitEncoding{$ENDIF});
  Result := BytesToStringRaw(FSSPIClient.UpdateAndBuildType3Message(LastMsg));
end;

function TSaslNtlm.IsReadyToStart: Boolean;
begin
  Result := True;
end;

class function TSaslNtlm.ServiceName: TIdSASLServiceName;
begin
  Result := 'NTLM';
end;

And then it is simply a matter of adding this SASL mechanism to the SMTP client: 然后只需将此SASL机制添加到SMTP客户端即可:

smtp.AuthType := satSASL;
ntml := TSaslNtlm.Create(smtp);
with smtp.SASLMechanisms.Add do begin
  DisplayName := ntlm.ServiceName;
  SASL := ntlm;
end;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM