作者:罗然8_907 | 来源:互联网 | 2023-09-24 12:59
FromapreviousquestionhereIlearnedhowtouseINDYSMTP(TIdSMTP)tosendmailswithanOffice
From a previous question here I learned how to use INDY SMTP (TIdSMTP) to send mails with an Office 365 account. 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. Some time ago there were SASL-NTLM components shipped with indy, but it seems they have been removed. I need NTLM to connect to a local Exchange Server. But I can't figure out how to do this without NTLM.
从上一个问题我在这里学习了如何使用INDY SMTP(TIdSMTP)发送带有Office 365帐户的邮件。我也想到了许多其他人,它适用于几乎所有常见的电子邮件提供商。但我无法弄清楚如何将它与我的本地Exchange Server一起使用。前段时间有一些带有indy的SASL-NTLM组件,但它们似乎已被删除。我需要NTLM连接到本地Exchange Server。但是如果没有NTLM,我无法弄清楚如何做到这一点。
1 个解决方案
0
I have recently struggled with Indy and my Exchange server as well. The SaslNtlm component is not in the version of Indy10 shipped with Delphi XE5. It is not even in the source files of the Indy Protocols folder.
我最近也在努力与Indy和我的Exchange服务器竞争。 SaslNtlm组件不在Delphi XE5附带的Indy10版本中。它甚至不在Indy Protocols文件夹的源文件中。
Fortunately a lot of the stuff required to do NTLM authentication with the SMTP client is available. There is a unit called IdAuthenticationSSPI which implements the entire NTLM exchange. All that was left to do was to implement a custom descendant from TIdSASL which interacts with the TIndySSPINTLMClient object.
幸运的是,可以使用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;
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;