【发布时间】:2011-08-31 11:17:45
【问题描述】:
我的 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 响应。
【问题讨论】:
-
我想有效地“进行身份验证”一次,并在 HttpWebRequests 中重用它。而不是每次我访问服务器时都进行身份验证。不过,我可能误解了 NTLM,实际上 NTLM 对每个请求都施加了额外请求的开销。
-
它最初工作方式的问题是对服务器的每个请求都会导致 3 个底层 HTTP 请求/响应。将 PreAuthenticate 设置为 True,它会下降到 2。但是应用程序是否可以“修复”以便每个 HTTP 请求只发出一个请求/响应(当然,除了初始请求)?如果可能,我想避免每个 HTTP 请求两个请求所涉及的网络流量开销。
-
@Ben:每个额外的请求都意味着到服务器的一次往返。虽然这并不意味着太多的流量,但它会降低每个请求的速度 - 从发送请求到准备好响应之间的持续时间几乎翻了一番,即使在快速连接中也是如此。
-
@Ben 在我看来,几十毫秒是一个非常非常长的时间!是的,程序员倾向于在他们的代码中进行许多不需要的优化,这可能会节省一些时钟周期。但是考虑一下今天的 CPU 每毫秒可以进行多少计算。 50ms 的时间对用户来说是相当明显的,优化它们是让软件变得活泼的原因。另外,如果吞吐量很重要(您按顺序发出许多请求),这将使请求/秒加倍。所以,基本上我同意你的观点,但它取决于用例的要求。
-
@Ben IMO 如果可能的话,服务器往返值得优化。我不会称其为微优化。但是,如果我找不到解决方案 - 这不是世界末日!
标签: c# httpwebrequest ntlm networkcredentials