C# WebClient.DownloadData(uri)HTTP NTLM身份验证失败,401使用了正确的凭据
我有以下代码:C# WebClient.DownloadData(uri)HTTP NTLM身份验证失败,401使用了正确的凭据,c#,asp.net,authentication,C#,Asp.net,Authentication,我有以下代码: using (WebClient wcli = new WebClient()) { wcli.UseDefaultCredentials = true; wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain"); byte[] buff = wcli.DownloadData(www); HttpContext.Current.Res
using (WebClient wcli = new WebClient())
{
wcli.UseDefaultCredentials = true;
wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain");
byte[] buff = wcli.DownloadData(www);
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" + reportName + ".pdf\"");
HttpContext.Current.Response.ContentType = "application/pdf";
HttpContext.Current.Response.BinaryWrite(buff);
HttpContext.Current.Response.Flush();
HttpContext.Current.Response.End();
}
我使用它获得SSRS 2014中报告的结果,并将其作为文档从我的web应用程序下载(在.Net 3.5中,托管在Windows 8.1、IIS 8.5上)
我遇到的问题是,在调用wcli.DownloadData(www)
时,我不断获得401未经授权的权限(请注意,使用任何浏览器时,报告都可以使用所使用的凭据正常工作)
我进行了TCP转储,发现NTLM握手没有发生:
wcli.UseDefaultCredentials=true代码>但您也在传递网络凭据。如果它们都使用相同的代码,那么另一个有效的代码可能会有效,因为它的用户具有访问权限
using (WebClient wcli = new WebClient())
{
wcli.UseDefaultCredentials = true;
wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain");
}
然而,这可能不是你的错误。我发现了这篇文章:
它提到需要使用HTTP keep alive来保持TCP连接为NTLM握手打开。握手刚刚结束的事实让我想到,也许这也是问题所在。我会检查以确认keep alive确实处于启用状态。我也遇到了同样的问题,在我的情况下(仍然是.Net4.5),有效的方法是使用:
WebClient wc = new WebClient();
wc.UseDefaultCredentials = false;
string host = "http://localhost"; //this comes from a function in my code
var myCredentialCache = new System.Net.CredentialCache();
myCredentialCache.Add(new Uri(host + "/"), "NTLM", new System.Net.NetworkCredential(accessUser, accessPassword, domain));
wc.Credentials = myCredentialCache;
var result = wc.DownloadFile(www);
对我来说,主要的区别是使用CredentialCache并设置主机uri,同时网络凭据中的域matter中的“保持活动”设置在默认情况下处于启用状态。我只是想知道它是否与IIS应用程序池无关,因为.Net 4.5应用程序使用的是“.Net 4.5”池,而.Net 3.5应用程序使用的是“.Net 4.5”池(它失败了)使用“Classic.Net AppPool”。你可以试试。但是如果它们在不同的应用程序池下,那么可能是用户。两个应用程序池的用户不同吗?我会查看用户。正如我提到的,你的代码说使用默认用户。因此,看看你是否将用户更改为与正常工作的用户相同的用户。根据,<代码>WebClient.UseDefaultCredentials=true
仅将WebClient.Credentials
预设为CredentialCache.DefaultCredentials
,然后由新网络凭据(“RS\u用户名”、“RS\u密码”、“RS\u域”)覆盖
.NB:我试图找出原因时只使用了CredentialCache.DefaultCredentials
,结果是403禁止