我有以下代码:
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中,托管在Window 8.1,IIS 8.5上)。
我遇到的问题是,在调用wcli.DownloadData(www)
时,我一直收到 401 Unauthorized (注意使用任何浏览器,报告在使用的凭据下工作正常)
我已经完成了TCP转储,我发现NTLM握手没有发生:
托管在同一台机器上但使用.Net 4.5的另一个应用程序使用相同的代码而没有任何问题。
我认为它必须是由于缺少/错误的配置,但我没有成功找出哪一个。 有什么想法吗?
我忘记提到的是,所提到的两个Web应用程序(都在同一服务器和IIS上托管)都连接到同一个Reporting Services服务器(但是不同的文件夹)。
答案 0 :(得分:0)
您告诉WebClient使用DefaultCredentials。 wcli.UseDefaultCredentials = true;
但您也传递了NetworkCredential。也许其他可用的代码,如果它们都使用相同的代码,则可以正常工作,因为它的用户可以访问。
using (WebClient wcli = new WebClient())
{
wcli.UseDefaultCredentials = true;
wcli.Credentials = new NetworkCredential("RS_Username", "RS_Password", "RS_Domain");
}
然而,这可能不是你的错误。发现这篇文章:http://www.benjaminathawes.com/2010/10/14/ntlms-dependency-on-http-keep-alives-another-cause-of-the-dreaded-401-1-error/。
它提到需要使用HTTP keep-alive来保持TCP连接为NTLM握手打开。握手刚刚死亡这一事实让我觉得这可能也是问题所在。我会检查以确认保持活着的确存在。
答案 1 :(得分:0)
我遇到了同样的问题,在我的案例中(Still .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,也是网络凭证中的域