我的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的响应。
答案 0 :(得分:3)
执行NTLM后发送的最后一个请求(导致200响应的请求)包含一个auth标头,告诉服务器您拥有正确的凭据。
我不确定客户端类是否具有保持此功能的功能,但如果您找到某种方法来保留此标头并将其添加到后续请求中,它应该可以正常工作。
更新:NTLM验证连接,因此您需要使用Keep-Alive标头保持连接打开。客户端类应该为此提供一些设置。有关更多信息,请参阅此页面,我发现该页面对NTLM方案非常有用和清晰:
答案 1 :(得分:1)
也许为时已晚,但是您必须在WebRequestHandler中将UnsafeAuthenticatedConnectionSharing
属性设置为true(它扩展了HttpClientHandler)。
这样,通过允许HttpClient在其他请求中“共享”身份验证来保持活动状态,同时允许保持活动状态(即使您自己设置标头也无法手动执行此操作)。请记住,您还应该在服务器中拥有适当的持久授权,对于Kerberos,请使用authPersistNonNTLM
,对于NTLM,请使用authPersistSingleRequest
。