考虑一个简单的C#.NET Framework 4.0应用程序:
这是一个可以正常运行的样本:
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();
}
}
}
问题:
启用跟踪时,我发现NTLM身份验证不会持续存在。
每次调用Webclient.DownloadString时,NTLM身份验证都会启动(服务器返回&#34; WWW-Authenticate:NTLM&#34;标头和整个身份验证/授权过程重复;没有&#34;连接:关闭&# 34;标题)。
是不是NTLM应该验证连接,而不是请求?
有没有办法让WebClient重用现有连接以避免重新验证每个请求?
答案 0 :(得分:13)
经过10天尝试我能想到的一切并在此过程中学到很多东西,我终于想出了解决这个问题的方法。
诀窍是通过覆盖GetWebRequest
来启用UnsafeAuthenticatedConnectionSharing
,并在您获得的true
中将属性设置为HttpWebRequest
。
您可能希望将其与ConnectionGroupName
属性结合使用,以避免未经身份验证的应用程序对连接的潜在使用。
以下是修改后的问题样本按预期工作。它打开一个NTLM身份验证连接并重用它:
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"));
MyWebClient webClient = new MyWebClient();
webClient.Credentials = myCache;
for (int i = 1; i <= 5; i++)
{
string result = webClient.DownloadString(new Uri(URL_status));
Console.WriteLine("Try {0}: {1}", i, result);
}
Console.Write("Done");
Console.ReadKey();
}
}
public class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest request = base.GetWebRequest(address);
if (request is HttpWebRequest)
{
var myWebRequest = request as HttpWebRequest;
myWebRequest.UnsafeAuthenticatedConnectionSharing = true;
myWebRequest.KeepAlive = true;
}
return request;
}
}
}
此时我还要感谢@Falco Alexander提供所有帮助;虽然他的建议对我不起作用,但他确实指出了我正确的方向寻找并最终找到答案。
答案 1 :(得分:1)
检查您的IIS设置,但这应该是默认设置。
<windowsAuthentication
enabled="True"
authPersistSingleRequest="False"
UseKernelMode>
</windowsAuthentication>
参考:https://msdn.microsoft.com/en-us/library/aa347472.aspx
您是否检查了localhost IIS所在的区域?在使用WinInet时,这也是客户端的一个陷阱。检查WebClient
的默认行为。
编辑:
在重现错误之后,我可以弄清楚它是WebClient
缺少的NTLM 预身份验证实施,让您远离单个401请求:
var WebClient = new PreAuthWebClient();
WebClient.Credentials = new NetworkCredential("user", "pass","domain");
//Do your GETs
Public class PreAuthWebClient: WebClient
{
protected override WebRequest GetWebRequest (Uri address)
{
WebRequest request = (WebRequest) base.GetWebRequest (address);
request.PreAuthenticate = true;
return request;
}
}