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 下载时超时

WebClient UploadFile 错误

通过 HTTP 302 重定向从 WebClient 获取位置?

服务器提交了协议冲突. Section=ResponseStatusLine

获取电脑中所安装的软件

获取电脑中所安装的软件