C# 如何';共享';跨多个HttpWebRequests的NTLM身份验证?

C# 如何';共享';跨多个HttpWebRequests的NTLM身份验证?,c#,httpwebrequest,ntlm,networkcredentials,C#,Httpwebrequest,Ntlm,Networkcredentials,我的C#应用程序访问使用NTLM身份验证的web服务器 我发现向服务器发出的每个请求(使用新的HttpWebRequest)都经过单独的身份验证。换句话说,每个请求都会产生401响应,之后在我得到实际响应之前会发生NTLM握手对话 e、 g: 首次获取请求: -> GET xyz <- 401 error (WWW-Authenticate:NTLM) -> GET xyz (Authorization:NTLM base64stuff) <- 401 error (

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

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

e、 g:

首次获取请求:

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

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

-> GET xyz (Authorization: base64stuff)
<- 200
->获取xyz
获取xyz(授权:NTLM base64stuff)
获取xyz(授权:base64stuff)
获取xyz(授权:NTLM base64stuff)
获取xyz(授权:base64stuff)

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

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


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


也许现在进行此操作有点太晚了,但是您必须在WebRequestHandler中将
UnsafeAuthenticatedConnectionSharing
属性设置为true(它扩展了HttpClientHandler)


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

您试图解决的问题是什么?我想有效地“执行身份验证”一次,并在HttpWebRequests之间重复使用。而不是每次我点击服务器时都进行身份验证。我可能误解了NTLM,事实上,NTLM会在每个请求上增加额外请求的开销。是的,但它现在的工作方式有什么问题,如果将您描述的行为改变为您想要的行为,它会解决什么问题,在现实世界中,您试图实现什么。它最初的工作方式存在的问题是,对服务器的每个请求都会导致3个底层HTTP请求/响应。当PreAuthenticate设置为True时,该值将降至2。但是,应用程序是否可以“修复”,以便每个HTTP请求只发出一个请求/响应(当然,除了最初的请求)?如果可能的话,我希望避免每个HTTP请求两个请求所涉及的网络流量开销。我仍然不确定您试图解决的问题,即每个页面请求两个身份验证请求不是“问题”,它只是对正在发生的情况的描述,额外请求的少量额外开销会导致什么问题?它会破坏什么东西吗?它会花费你的钱吗?如果你删除它,你会有更少的服务器或更少的带宽吗?嗯。可以在HttpWebRequest上设置授权头,我试过了。但是它不起作用-服务器返回一个400错误请求,表明授权头不能以这种方式“重放”。出于安全原因,我认为这是有意义的。在做了一点测试之后,尽管HttpWebRequest有一个KeepAlive属性,但它看起来并没有比设置PreAuthenticate=true更好。有点烦人。@mackenir:你解决这个问题了吗?我也看到了与你上面描述的完全相同的问题。将PreAuthenticate和KeepAlive设置为true似乎没有帮助。
-> GET xyz (Authorization:NTLM base64stuff)
<- 401 error (WWW-Authenticate:NTLM) //can this request be avoided?

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