通过HTTPS授权失败TIdHTTP

时间:2012-11-12 14:27:15

标签: delphi delphi-xe2 indy

我想接近Exchange Web服务并自己处理XML SOAP组合(请求)和解析(响应)。 因此,THTPPRIO似乎有点矫枉过正。

我正在尝试TIdHTTP,但我坚持认证;使用Delphi XE2更新4和Indy 10.5.8.0

以下是代码:

idHTTP1.Request.CustomHeaders.AddValue('SOAPAction','"http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"');
IdHTTP1.Post('https://webmail.mailserver.nl/ews/exchange.asmx',TSRequest,TSResponse);
  • TSRequest,TSResponse是UTF-8 TStringStreams,TSRequest包含 整个SOAP信封
  • IdHTTP1.IOHandler设置为a TIdSSLIOHandlerSocketOpenSSL,每this advice TIdSSLIOHandlerSocketOpenSSL.Intercept链接到TIdLogDebug 我可以调试正在发生的事情
  • OpenSSL DLL存在于DLL搜索路径中
  • EWS需要NTLM验证; TIdNTLMAuthentication在uses子句中;我有 设置idHTTP1.Request.BasicAuthentication = false,用户名和 填写密码
  • IdHTTP1.OnSelectAuthorization事件确认NTLM身份验证 (参数AuthenticationClass = TIdSSPINTLMAuthentication,和 AuthInfo TIdHeaderList包含'谈判','NTLM')
  • 没有代理。我通过Fiddler代理,看看是什么 继续,但没有区别。

我也尝试过设置用户/ PW运行时间:

procedure TForm1.IdHTTP1Authorization(Sender: TObject; Authentication: TIdAuthentication; var Handled: Boolean);
begin
  Authentication.Username := 'bob@domain.nl';
  Authentication.Password := 'password';
  Handled := true;
end;

发送的HTTP(来自TIdLogDebug.OnSend)以:

开头
POST /ews/exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 562
SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"
Host: webmail.mailserver.nl
Accept: text/html, */*
Accept-Encoding: gzip,deflate, identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)


<soapenv:Envelope 

收到的HTTP(来自TIdLogDebug.OnReceive)是

HTTP/1.1 401 Unauthorized
Cache-Control: private
Server: Microsoft-IIS/7.5
X-AspNet-Version: 2.0.50727
Set-Cookie: exchangecookie=0157734634ba4a0fa3a7d0d8efb602f2; expires=Tue, 12-Nov-2013 13:38:56 GMT; path=/; HttpOnly
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Mon, 12 Nov 2012 13:38:56 GMT
Content-Length: 0

TIdSSLIOHandlerSocketOpenSSL.OnStatusInfo事​​件日志

SSL status: "before/connect initialization"
SSL status: "before/connect initialization"
SSL status: "SSLv3 write client hello A"
SSL status: "SSLv3 read server hello A"
SSL status: "SSLv3 read server certificate A"
SSL status: "SSLv3 read server done A"
SSL status: "SSLv3 write client key exchange A"
SSL status: "SSLv3 write change cipher spec A"
SSL status: "SSLv3 write finished A"
SSL status: "SSLv3 flush data"
SSL status: "SSLv3 read finished A"
SSL status: "SSL negotiation finished successfully"
SSL status: "SSL negotiation finished successfully"
Cipher: name = AES128-SHA; description = AES128-SHA              SSLv3 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA1
; bits = 128; version = TLSv1/SSLv3;

我在传出的HTTP中错过的是一行(例如由SOAPUI生成):

"Authorization: NTLM TlRMTVNTUAABAAAANQIIIBQAFAAyAAAAEgASACAAAABWAE0ASgBBAE4AVABUADcANABUAEkATQBFAFQARQBMAEwAQgBWAA==[\r][\n]"

也许我没有在正确的位置指定用户名/ PW?

在Remy的初步回答之后添加了11月13日:

为了进行比较,我从SOAPUI调用了web服务,这显示 6个数据包越过该行,响应两次UnAuthorized。

>> "POST /ews/exchange.asmx HTTP/1.1[\r][\n]"
>> "Accept-Encoding: gzip,deflate[\r][\n]"
>> "SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"[\r][\n]"
>> "Content-Type: text/xml; charset=utf-8[\r][\n]"
>> "Content-Length: 548[\r][\n]"
>> "Host: webmail.timetellbv.nl[\r][\n]"
>> "Connection: Keep-Alive[\r][\n]"
>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"
>> "[\r][\n]"
>> "<soapenv:Envelope [\n]"
[snip]
>> "</soapenv:Envelope>[\n]"
>> "[\n]"

<< "HTTP/1.1 401 Unauthorized[\r][\n]"
<< "Cache-Control: private[\r][\n]"
<< "Server: Microsoft-IIS/7.5[\r][\n]"
<< "X-AspNet-Version: 2.0.50727[\r][\n]"
<< "Set-Cookie: exchangecookie=a29f10ca2a6d484ea276737e87d8e733; expires=Wed, 13-Nov-2013 10:47:33 GMT; path=/; HttpOnly[\r][\n]"
<< "WWW-Authenticate: Negotiate[\r][\n]"
<< "WWW-Authenticate: NTLM[\r][\n]"
<< "X-Powered-By: ASP.NET[\r][\n]"
<< "Date: Tue, 13 Nov 2012 10:47:33 GMT[\r][\n]"
<< "Content-Length: 0[\r][\n]"
<< "[\r][\n]"

>> "POST /ews/exchange.asmx HTTP/1.1[\r][\n]"
>> "Accept-Encoding: gzip,deflate[\r][\n]"
>> "SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"[\r][\n]"
>> "Content-Type: text/xml; charset=utf-8[\r][\n]"
>> "Content-Length: 548[\r][\n]"
>> "Host: webmail.timetellbv.nl[\r][\n]"
>> "Connection: Keep-Alive[\r][\n]"
>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"
>> "Cookie: exchangecookie=a29f10ca2a6d484ea276737e87d8e733[\r][\n]"
>> "Cookie2: $Version=1[\r][\n]"
>> "Authorization: NTLM TlRMTVNTUAABAAAANQIIIBQAFAAyAAAAEgASACAAAABWAE0ASgBBAE4AVABUADcANABUAEkATQBFAFQARQBMAEwAQgBWAA==[\r][\n]"
>> "[\r][\n]"
>> "<soapenv:Envelope [\n]"
[snip]
>> "</soapenv:Envelope>[\n]"
>> "[\n]"

<< "HTTP/1.1 401 Unauthorized[\r][\n]"
<< "Server: Microsoft-IIS/7.5[\r][\n]"
<< "WWW-Authenticate: NTLM TlRMTVNTUAACAAAAFAAUADgAAAA1AokilFuJDu09j+sAAAAAAAAAAMAAwABMAAAABgGxHQAAAA9UAEkATQBFAFQARQBMAEwAQgBWAAIAFABUAEkATQBFAFQARQBMAEwAQgBWAAEAHABUAFQARQBYAEMASABBAE4ARwBFADIAMAAxADAABAAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwAAwA4AFQAVABFAFgAQwBIAEEATgBHAEUAMgAwADEAMAAuAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABQAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABwAIADs8RkmMwc0BAAAAAA==[\r][\n]"
<< "WWW-Authenticate: Negotiate[\r][\n]"
<< "X-Powered-By: ASP.NET[\r][\n]"
<< "Date: Tue, 13 Nov 2012 10:47:33 GMT[\r][\n]"
<< "Content-Length: 0[\r][\n]"
<< "[\r][\n]"

>> "POST /ews/exchange.asmx HTTP/1.1[\r][\n]"
>> "Accept-Encoding: gzip,deflate[\r][\n]"
>> "SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"[\r][\n]"
>> "Content-Type: text/xml; charset=utf-8[\r][\n]"
>> "Content-Length: 548[\r][\n]"
>> "Host: webmail.timetellbv.nl[\r][\n]"
>> "Connection: Keep-Alive[\r][\n]"
>> "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)[\r][\n]"
>> "Cookie: exchangecookie=a29f10ca2a6d484ea276737e87d8e733[\r][\n]"
>> "Cookie2: $Version=1[\r][\n]"
>> "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAADsAOwAWAAAABQAFABEAQAAEgASAFgBAAASABIAagEAAAAAAAB8AQAANQIIIFEqBrpeBXvnS3dcDcbKGMQS3VgaBa9Bi9YvouCOFFWFjH84AhcR7fgBAQAAAAAAAECzkUmMwc0BEt1YGgWvQYsAAAAAAgAUAFQASQBNAEUAVABFAEwATABCAFYAAQAcAFQAVABFAFgAQwBIAEEATgBHAEUAMgAwADEAMAAEABoAdABpAG0AZQB0AGUAbABsAGIAdgAuAG4AbAADADgAVABUAEUAWABDAEgAQQBOAEcARQAyADAAMQAwAC4AdABpAG0AZQB0AGUAbABsAGIAdgAuAG4AbAAFABoAdABpAG0AZQB0AGUAbABsAGIAdgAuAG4AbAAHAAgAOzxGSYzBzQEAAAAAVABJAE0ARQBUAEUATABMAEIAVgBkAGUAdgBlAGwAbwBwAGUAcgBWAE0ASgBBAE4AVABUADcANAA=[\r][\n]"
>> "[\r][\n]"
>> "<soapenv:Envelope [\n]"
[snip]
>> "</soapenv:Envelope>[\n]"
>> "[\n]"

<< "HTTP/1.1 200 OK[\r][\n]"
<< "Cache-Control: private[\r][\n]"
<< "Transfer-Encoding: chunked[\r][\n]"
<< "Content-Type: text/xml; charset=utf-8[\r][\n]"
<< "Server: Microsoft-IIS/7.5[\r][\n]"
<< "X-EwsPerformanceData: RpcC=2;RpcL=0;LdapC=1;LdapL=0;[\r][\n]"
<< "X-AspNet-Version: 2.0.50727[\r][\n]"
<< "Persistent-Auth: true[\r][\n]"
<< "X-Powered-By: ASP.NET[\r][\n]"
<< "Date: Tue, 13 Nov 2012 10:47:33 GMT[\r][\n]"
<< "[\r][\n]"
<< "877[\r][\n]"
<< "<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
[snip]
<< "</s:Envelope>"
<< "[\r][\n]"
<< "0[\r][\n]"
<< "[\r][\n]"

所以从Delphi我只看到前2个数据包交换。奇怪的是,如果我再次单击“测试”按钮 ,交换似乎会继续???:

请求:

POST /ews/exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 562
SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"
Host: webmail.timetellbv.nl
Accept: text/html, */*
Accept-Encoding: gzip,deflate, identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)
Authorization: NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw==


<soapenv:Envelope 
[snip]
</soapenv:Envelope>

响应:

HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/7.5
WWW-Authenticate: NTLM TlRMTVNTUAACAAAAFAAUADgAAAAFgomiqrTrZnWjEdQAAAAAAAAAAMAAwABMAAAABgGxHQAAAA9UAEkATQBFAFQARQBMAEwAQgBWAAIAFABUAEkATQBFAFQARQBMAEwAQgBWAAEAHABUAFQARQBYAEMASABBAE4ARwBFADIAMAAxADAABAAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwAAwA4AFQAVABFAFgAQwBIAEEATgBHAEUAMgAwADEAMAAuAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABQAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABwAIAOZ26g+Owc0BAAAAAA==
Set-Cookie: exchangecookie=0c8362d303d742c6aae98bd1df574a4d; expires=Wed, 13-Nov-2013 11:00:16 GMT; path=/; HttpOnly
WWW-Authenticate: Negotiate
X-Powered-By: ASP.NET
Date: Tue, 13 Nov 2012 11:00:15 GMT
Content-Length: 0

如果我点击我的测试按钮第三次,我会得到一个实际的EIdHTTPProtocolException和这个数据交换:

请求:

POST /ews/exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 562
SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/ResolveNames"
Host: webmail.timetellbv.nl
Accept: text/html, */*
Accept-Encoding: gzip,deflate, identity
User-Agent: Mozilla/3.0 (compatible; Indy Library)
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAJ4AAABIAUgBtgAAABIAEgBYAAAAIgAiAGoAAAASABIAjAAAAAAAAAD+AQAABYKIogYBsR0AAAAPOcYXUTHWwFnGL17GZCkaYFYATQBKAEEATgBUAFQANwA0AGIAbwBiAEAAdABpAG0AZQB0AGUAbABsAGIAdgAuAG4AbABWAE0ASgBBAE4AVABUADcANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEi/nFDXHEgQ6OUgBv7Zw0AQEAAAAAAACsq9CKkcHNAbBRNkiUgQdnAAAAAAIAFABUAEkATQBFAFQARQBMAEwAQgBWAAEAHABUAFQARQBYAEMASABBAE4ARwBFADIAMAAxADAABAAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwAAwA4AFQAVABFAFgAQwBIAEEATgBHAEUAMgAwADEAMAAuAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABQAaAHQAaQBtAGUAdABlAGwAbABiAHYALgBuAGwABwAIAKyr0IqRwc0BBgAEAAIAAAAIADAAMAAAAAAAAAAAAAAAADAAALSZIBVpzBPWjPvSVUels19vMlDT5yE5Q8qQ4mwV87EeCgAQAAAAAAAAAAAAAAAAAAAAAAAJAAAAAAAAAAAAAAAAAAAA


<soapenv:Envelope 
[snip]
</soapenv:Envelope>

响应:

HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/7.5
Set-Cookie: exchangecookie=2a4876f8adeb425384fb370cafa61ee6; expires=Wed, 13-Nov-2013 11:25:11 GMT; path=/; HttpOnly
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
X-Powered-By: ASP.NET
Date: Tue, 13 Nov 2012 11:25:11 GMT
Content-Length: 0

感谢

1 个答案:

答案 0 :(得分:4)

通常,在服务器通过401回复请求之前,不会发送Authorization标头。您不会在初始请求中看到它,但TIdHTTP应该在处理401回复后发送带有Authorization标头的新请求。在任何情况下,您都应该使用TIdHTTP.Request.UsernameTIdHTTP.Request.Password属性来设置初始凭据,然后使用OnAuthorization事件根据需要提供新凭据。