7

我的 C# 应用程序访问了使用 NTLM 身份验证的 Web 服务器。

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

例如:

第一个 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 响应。

4

2 回答 2

4

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

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


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

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

于 2011-08-31T11:55:09.973 回答
1

也许它有点太晚了,但你必须UnsafeAuthenticatedConnectionSharing在 WebRequestHandler 中将属性设置为 true(它扩展了 HttpClientHandler)。

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

于 2018-08-20T13:42:37.950 回答