如何跨多个HttpWebRequests“共享”NTLM身份验证?

时间:2011-08-31 11:17:45

标签: c# httpwebrequest ntlm networkcredentials

我的C#应用​​程序点击使用NTLM身份验证的Web服务器。

我发现每个向服务器发出的请求(使用新的HttpWebRequest)都是单独验证的。换句话说,每个请求都会产生401响应,然后在我获得实际响应之前发生NTLM握手会话。

e.g:

第一个GET请求:

-> GET xyz 
<- 401 error (WWW-Authenticate:NTLM)

-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM base64stuff)

-> GET xyz (Authorization: base64stuff)
<- 200

后续请求:

-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM) //can this request be avoided?

-> GET xyz (Authorization: base64stuff)
<- 200

(最初,在PreAuthenticate设置为false的情况下,后续请求看起来像第一个请求 - 即每个'请求有三个基础请求')

有没有办法通过后续的HttpWebRequests“共享”第一次请求对服务器执行的身份验证?

我想也许UnsafeAuthenticatedConnectionSharing属性允许我这样做,但是对于应用程序中使用的所有HttpWebRequest对象将其设置为true都没有效果。

但是,如果我将PreAuthenticate设置为true,则在第一个请求之后,每个请求会发生少于401的响应。

2 个答案:

答案 0 :(得分:3)

执行NTLM后发送的最后一个请求(导致200响应的请求)包含一个auth标头,告诉服务器您拥有正确的凭据。

我不确定客户端类是否具有保持此功能的功能,但如果您找到某种方法来保留此标头并将其添加到后续请求中,它应该可以正常工作。


更新:NTLM验证连接,因此您需要使用Keep-Alive标头保持连接打开。客户端类应该为此提供一些设置。有关更多信息,请参阅此页面,我发现该页面对NTLM方案非常有用和清晰:

http://www.innovation.ch/personal/ronald/ntlm.html

答案 1 :(得分:1)

也许为时已晚,但是您必须在WebRequestHandler中将UnsafeAuthenticatedConnectionSharing属性设置为true(它扩展了HttpClientHandler)。

这样,通过允许HttpClient在其他请求中“共享”身份验证来保持活动状态,同时允许保持活动状态(即使您自己设置标头也无法手动执行此操作)。请记住,您还应该在服务器中拥有适当的持久授权,对于Kerberos,请使用authPersistNonNTLM,对于NTLM,请使用authPersistSingleRequest