将INDY 10与Exchange SMTP-Server一起使用

时间:2013-08-30 21:16:27

标签: delphi email smtp exchange-server indy

从上一个问题here我学习了如何使用INDY SMTP(TIdSMTP)发送带有Office 365帐户的邮件。我也想到了许多其他人,它适用于几乎所有常见的电子邮件提供商。但我无法弄清楚如何将它与我的本地Exchange Server一起使用。前段时间有一些带有indy的SASL-NTLM组件,但它们似乎已被删除。我需要NTLM连接到本地Exchange Server。但如果没有NTLM,我无法弄清楚如何做到这一点。

1 个答案:

答案 0 :(得分:1)

我最近也在努力与Indy和我的Exchange服务器竞争。 SaslNtlm组件不在Delphi XE5附带的Indy10版本中。它甚至不在Indy Protocols文件夹的源文件中。

幸运的是,可以使用SMTP客户端进行NTLM身份验证所需的许多内容。有一个名为IdAuthenticationSSPI的单元,它实现了整个NTLM交换。剩下要做的就是实现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;

该类的实现如下:

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;

然后只需将此SASL机制添加到SMTP客户端即可:

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