2013-08-30 187 views
0

從上一個問題here我學會了如何使用INDY SMTP(TIdSMTP)發送帶有Office 365帳戶的郵件。我也爲其他許多人弄明白了這一點,它適用於幾乎所有常見的電子郵件提供商。但我無法弄清楚如何使用它與我的本地Exchange Server。前段時間有indy附帶的SASL-NTLM組件,但似乎它們已被刪除。我需要NTLM連接到本地Exchange Server。但是我不知道如何在沒有NTLM的情況下做到這一點。使用INDY 10與Exchange SMTP服務器

+1

有什麼具體的問題你有嗎?如果你不解釋「那個問題」是什麼,我們很難提供如何解決問題的建議。請編輯您的問題並提出更具體的問題,以便我們嘗試並幫助您解決問題。 –

+0

Suppprt for NTLM SASL未被刪除。它從來沒有最終確定。 'TIdSASLNTLM'組件仍然存在,在'IdSASL_NTLM.pas'單元中,默認情況下它沒有在組件面板上註冊,但是你可以在代碼中可編程地實例化它。 –

+0

@RemyLebeau:在我的INDY版本(Indy 10與XE2一起提供)中不存在「IdSASL_NTLM.pas」。我只擁有「IdNTLM.pas」。 KenWhite:我將添加我明天使用其他SALS方法(或者根本沒有SASL)時得到的錯誤,與交換服務器在一起的機器不在家中。 – Timestop

回答

0

我最近和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;