2009-06-23 123 views
12

我想在WinForms应用程序中使用System.Net.WebClient将文件上传到具有Windows身份验证的IIS6服务器,因为它只有'Authentication'方法。System.Net.WebClient不适用于Windows身份验证

WebClient myWebClient = new WebClient(); 
myWebClient.Credentials = new System.Net.NetworkCredential(@"boxname\peter", "mypassword"); 
byte[] responseArray = myWebClient.UploadFile("http://localhost/upload.aspx", fileName); 

我收到了 '远程服务器返回错误:(401)未经授权',实际上它是一个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 

我用进程监视器和提琴手调查,但无济于事。

这为什么这个工程适用于第三方浏览器,但不适用于IE或System.Net.WebClient?

+0

从集成Windows改变IIS的单一身份验证方法为基本后它的工作原理,但并没有解决我的问题,因为我不能改变生产服务器上设置。 – 2009-06-23 01:54:32

+0

我使用IIS的身份验证和访问控制诊断工具来监视进程,并将Firefox的日志与IE的日志进行比较。在NTLM挑战/响应失败之前,它看起来一切正常,但它也没有给我任何线索。 – 2009-07-04 22:11:18

+0

我做了一些更多的测试:上面介绍的2003 Server实际上是虚拟PC中的虚拟机,当使用来自主机的IE时,我可以进行身份​​验证,但不能在来宾上使用IE。但是,使用访客的IE在使用站点的IP地址时可以工作,而不是通过主机文件设置的主机名。有些事情在这里破裂!我很高兴它不在生产服务器上。 – 2009-07-17 19:24:06

回答

18

我看到过类似的问题,其中集成/ NTLM安全性只有在通过计算机名或本地主机访问主机时才起作用。事实上,这是Windows中一个[糟糕的]文档功能,旨在防止“反射攻击”。

基本上,您需要在试图访问服务器的计算机上创建注册表项,并将您试图访问的域列入白名单。每个主机名/ FQDN需要在自己的行上 - 没有通配符,名称必须完全匹配。从KB文章:

  • 单击开始,单击运行,键入regedit,然后单击确定。
  • 在注册表编辑器,找到并单击下面的注册表项: HKEY_LOCAL_MACHINE \系统\ CurrentControlSet \控制\ LSA \ MSV1_0
  • 右键单击MSV1_0,指向新建,然后单击多字符串值。
  • 类型BackConnectionHostNames,然后按ENTER键。
  • 用鼠标右键单击BackConnectionHostNames,然后单击修改。
  • 在数值数据框中,键入本地计算机上的网站的主机名或主机名,然后单击确定。
  • 退出注册表编辑器,然后重新启动计算机。

http://support.microsoft.com/kb/956158/en-us

4

您是否尝试过...

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

+0

刚刚尝试过,同样的401.2响应和'失败审计' – 2009-06-23 01:18:21

+0

也尝试了'协商'版本,结果相同。什么让我吃惊,那在IE中也不起作用。 – 2009-06-23 01:27:06

0

不知道你的IIS部署,并假设你有正确的授权规则,在IIS中设置上传(例如正确的允许* ACL的右侧目录,你试图上传内容等),首先我会尝试将UseDefaultCredentials设置为true,而不是显式设置Credential。 (也许您认为您正在使用您正在设置的证书访问服务器,但情况并非如此?如果此操作可能会发生。)

这是一种非常常见的情况,因此我将重点介绍IIS的授权规则您尝试上传文件的目录,该目录上的实际ACL。例如。您的网站是否冒充或不?如果是,则必须在该目录上具有实际的ACL,否则无论在哪个帐户应用程序池上运行。

1

尝试进入IE的选项并明确将该站点添加到Intranet区域。然后重新运行该程序。您也不应该从管理员登录运行该程序。这可能会触发Enhanced Security Configuration for Internet Explorer

这可以解释为什么你可以使用Firefox和Opera访问网站,但不能使用IE或WebClient。

相关问题