System.Net.WebClient 不适用于 Windows 身份验证
Posted
技术标签:
【中文标题】System.Net.WebClient 不适用于 Windows 身份验证【英文标题】:System.Net.WebClient doesn't work with Windows Authentication 【发布时间】:2010-11-05 00:51:51 【问题描述】:我正在尝试在 WinForms 应用程序中使用 System.Net.WebClient 将文件上传到具有 Windows 身份验证的 IIS6 服务器 它只是“身份验证”方法。
WebClient myWebClient = new WebClient();
myWebClient.Credentials = new System.Net.NetworkCredential(@"boxname\peter", "mypassword");
byte[] responseArray = myWebClient.UploadFile("http://localhost/upload.aspx", fileName);
我收到“远程服务器返回错误:(401) Unauthorized”,实际上是 401.2
客户端和 IIS 都在同一台 Windows Server 2003 开发机器上。
当我尝试在 Firefox 中打开该页面并输入与代码中相同的正确凭据时,该页面出现了。 但是在使用 IE8 时,我得到了同样的 401.2 错误。
试过 Chrome 和 Opera,它们都可以工作。
我在 IE Internet 选项中启用了“启用集成 Windows 身份验证”。
安全事件日志有一个失败审计:
Logon Failure:
Reason: An error occurred during logon
User Name: peter
Domain: boxname
Logon Type: 3
Logon Process: ÈùÄ
Authentication Package: NTLM
Workstation Name: boxname
Status code: 0xC000006D
Substatus code: 0x0
Caller User Name: -
Caller Domain: -
Caller Logon ID: -
Caller Process ID: -
Transited Services: -
Source Network Address: 127.0.0.1
Source Port: 1476
我使用 Process Monitor 和 Fiddler 进行调查,但无济于事。
为什么这适用于 3rd 方浏览器,但不适用于 IE 或 System.Net.WebClient?
【问题讨论】:
将 IIS 中的单一身份验证方法从集成 Windows 更改为 Basic 后,它可以工作,但这并不能解决我的问题,因为我无法在生产服务器上更改该设置。 我使用 IIS 的“身份验证和访问控制诊断工具”来监控进程,并将 Firefox 的日志与 IE 的日志进行了比较。在 NTLM 质询/响应失败之前,它看起来一切正常,但它也没有给我任何线索,为什么会这样。 我做了更多测试:上面描述的2003 Server实际上是Virtual PC中的VM,当在主机上使用IE时我可以进行身份验证,但不能在guest上使用IE。但是,当使用站点的 IP 地址而不是通过主机文件设置的主机名时,使用来宾的 IE 可以正常工作。这里有些东西坏了!我很高兴它不在生产服务器上。 【参考方案1】:你试过了吗……
new NetworkCredential( "peter", "password", "boxname" );
你也可以试试……
var credCache = new CredentialCache();
credCache.Add( new Uri ("http://localhost/upload.aspx"),
"Negotiate",
new NetworkCredential("peter", "password", "boxname"));
wc.Credentials = credCache;
另外,根据this可能是IIS配置错误。尝试将上面的“协商”替换为“基本”,并检查网站的 IIS 配置。还有一堆可能的原因here。
【讨论】:
还尝试了“协商”版本,结果相同。让我感到困惑的是,它在 IE 中也不起作用。【参考方案2】:在不知道您的 IIS 部署的情况下,并假设您在 IIS 中设置了正确的上传授权规则(例如,您尝试将内容上传到的正确目录上的正确允许* ACL 等),首先我会尝试是将 UseDefaultCredentials 设置为 true,而不是显式设置 Credential。 (也许您认为您正在使用您设置的凭据访问服务器,但事实并非如此?如果这可行的话,那将是可能的。)
这是一种非常常见的情况,因此我将重点介绍您尝试上传文件的目录的 IIS 授权规则,即该目录上的实际 ACL。例如。您的网站是否在模仿?如果是,那么您必须在该目录上有实际的 ACL,否则无论正在运行的帐户应用程序池是什么。
【讨论】:
我认为这不是 ACL 问题,因为它没有达到那么远,Process Monitor 没有显示目标目录上的任何活动。 刚刚用 UseDefaultCredentials 尝试过,也失败了。我需要让它使用非默认凭据,因为 Windows 用户在生产中的客户端和服务器机器上是不同的。【参考方案3】:尝试进入 IE 的选项并将站点显式添加到 Intranet 区域。然后重新运行程序。您也不应该从管理员登录运行该程序。这可能会触发Enhanced Security Configuration for Internet Explorer。
这可以解释为什么您可以使用 Firefox 和 Opera 访问该站点,但不能使用 IE 或 WebClient。
【讨论】:
【参考方案4】:我看到了类似的问题,集成/NTLM 安全性仅在您通过机器名称或本地主机访问主机时才有效。事实上,它是 Windows 中一个 [糟糕的] 文档功能,旨在防止“反射攻击”。
基本上,您需要在尝试访问服务器的机器上创建一个注册表项,并将您尝试访问的域列入白名单。每个主机名/FQDN 都需要在自己的行中 - 没有通配符并且名称必须完全匹配。来自知识库文章:
单击开始,单击运行,键入 regedit,然后单击确定。 在注册表编辑器中,找到并单击以下注册表项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0 右键单击 MSV1_0,指向新建,然后单击多字符串值。 键入 BackConnectionHostNames,然后按 Enter。 右键单击BackConnectionHostNames,然后单击修改。 在“数值数据”框中,键入本地计算机上站点的一个或多个主机名,然后单击“确定”。 退出注册表编辑器,然后重新启动计算机。http://support.microsoft.com/kb/956158/en-us
【讨论】:
+10 如果我可以投票 10 次,我会的。结束了我 3 天的挠头和谷歌搜索。 以上链接现已失效。见support.microsoft.com/en-us/help/896861/…。它还包括另一个设置:创建和设置 DWORD 值 HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters\DisableStrictNameChecking=1以上是关于System.Net.WebClient 不适用于 Windows 身份验证的主要内容,如果未能解决你的问题,请参考以下文章
s-s-rS 报告使用 System.Net.WebClient 下载时超时
通过 HTTP 302 重定向从 WebClient 获取位置?