考虑一个简单的C#.NET Framework 4.0应用程序,它:
-
使用WebClient
-
使用NTLM进行身份验证(在IIS 6.0和IIS 7.5服务器上测试)
-
使用DownloadString()多次从URL检索字符串
这是一个工作正常的样本:
using System;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string URL_status = "http://localhost/status";
CredentialCache myCache = new CredentialCache();
myCache.Add(new Uri(URL_status), "NTLM", new NetworkCredential("username", "password", "domain"));
WebClient WebClient = new WebClient();
WebClient.Credentials = myCache;
for (int i = 1; i <= 5; i++)
{
string Result = WebClient.DownloadString(new Uri(URL_status));
Console.WriteLine("Try " + i.ToString() + ": " + Result);
}
Console.Write("Done");
Console.ReadKey();
}
}
}
The problem:
启用跟踪时,我发现NTLM身份验证不会持久存在 .
每次调用Webclient.DownloadString时,NTLM身份验证都会启动(服务器返回“WWW-Authenticate:NTLM”标头,并且整个身份验证/授权过程重复;没有“Connection:close”标头) .
是不是NTLM应该验证连接,而不是请求?
有没有办法让WebClient重用现有连接以避免重新验证每个请求?
2 回答
经过10天尝试我能想到的一切并在此过程中学到很多东西,我已经找到了解决这个问题的方法 .
诀窍是通过重写 HttpWebRequest 并将属性值设置为true来启用UnsafeAuthenticatedConnectionSharing .
您可能希望将其与ConnectionGroupName属性组合,以避免未经过身份验证的应用程序可能使用该连接 .
以下是问题的样本按预期工作 . 它打开一个NTLM身份验证连接并重用它:
在这一点上,我还要感谢@Falco Alexander的所有帮助;虽然他的建议对我不起作用,但他确实指出了我正确的方向寻找并最终找到答案 .
检查你的IIS的设置,例如,虽然这应该是默认的 .
参考:https://msdn.microsoft.com/en-us/library/aa347472.aspx
你检查了你的localhost IIS所在的区域吗?在使用WinInet时,这也是客户端的一个陷阱 . 检查WebClient的默认行为 .
编辑:
在重现错误后,我可以弄清楚它是WebClient缺少的NTLM preauthentication 实现,它使您免于单个401请求: