[英]C# WebClient NTLM authentication starting for each request
考虑一个简单的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身份验证都会启动(服务器返回“WWW-Authenticate:NTLM”标头,并且整个身份验证/授权过程重复;没有“Connection:close”标头)。
是不是NTLM应该验证连接,而不是请求?
有没有办法让WebClient重用现有连接以避免重新验证每个请求?
经过10天尝试我能想到的一切并在此过程中学到很多东西,我终于找到了解决这个问题的方法。
诀窍是通过重写GetWebRequest
并在您返回的HttpWebRequest
中将属性设置为true
来启用UnsafeAuthenticatedConnectionSharing
。
您可能希望将其与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的所有帮助; 虽然他的建议对我不起作用,但他确实指出了我正确的方向寻找并最终找到答案。
检查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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.