【问题标题】:IIS Not Passing Credentials with .NET WebClient ObjectIIS 未使用 .NET WebClient 对象传递凭据
【发布时间】:2014-05-05 18:25:17
【问题描述】:

好的,伙计们,这个问题已经困扰我好几天了。有很多类似问题的例子,但似乎没有一个适合我遇到的问题。我正在尝试使用 VB.NET System.Net.WebClient 对象远程导航到 ASP.NET 应用程序中的 Intranet 网页。在我的开发服务器上,我可以毫无错误地访问该页面。在我们的 UAT 服务器上,请求失败并出现 401 Unauthorized 错误。两台服务器都是使用 IIS8 的 Windows Server 2012。

编辑:(为了简单起见,我打算省略它,但我想它是相关的。这个 ASP.NET 网站包含在 SharePoint 2013 中。这个应用程序输出了一个 DLL,它由 SharePoint 与 ASP.NET 页面结合使用。两台服务器都具有为 SharePoint 网站指定的相同身份验证:

因此,实际上,唯一需要完成的身份验证是对 SharePoint 网站本身的身份验证。)

 

经过数小时的测试后,我决定查看 IIS 事务日志以尝试找出发生了什么。我发现无论我将什么凭据传递给 WebClient 对象,它们都不会被 IIS 传递给我的 UAT 服务器上的请求,而是在我的开发服务器上(请参阅下面的 IIS 事务日志)

据推测,这两个站点都被配置为彼此的精确副本,我已尽我所能比较了两台服务器之间网站的 IIS 设置,但我似乎无法弄清楚有什么区别。

 

下面是执行工作的函数的一些代码:

    Private Sub CreateTiffFile()
    Try
        'Create NetworkCredentials object and set properties
        Dim creds As New NetworkCredential
        creds.UserName = "userid"
        creds.Domain = "domain"
        creds.Password = "password"

        'Create WebClient object, set creds
        Dim wc As New System.Net.WebClient()
        wc.Credentials = creds

        'Set the URL to navigate to based on the current URL and RequestID
        _URL = Utility.CurrentURL & "PrintPreview.aspx?RequestId=" & _CurrentRequestID 

        'Read the page
        Dim webReader As New System.IO.StreamReader(wc.OpenRead(_URL))

        'Do other stuff here
        'Do other stuff here
        'etc.

    Catch ex As Exception
        Utility.ErrorHandler(ex, _CurrentRequestID)
    End Try
End Sub

开发 IIS 事务日志(凭据正确传递):

2014-05-05 14:59:38 10.###.###.### GET /mysite/PrintPreview.aspx RequestId=9849&HideControls=1 80 - 10.###.###.### - - 401 0 0 1481
2014-05-05 14:59:38 10.###.###.### GET /mysite/PrintPreview.aspx RequestId=9849&HideControls=1 80 - 10.###.###.### - - 401 1 2148074254 0
2014-05-05 14:59:58 10.###.###.### GET /mysite/PrintPreview.aspx RequestId=9849&HideControls=1 80 0#.w|domain\userid 10.###.###.### - - 200 0 0 19468

在最后一行,您会注意到凭据已通过并返回 200 OK

UAT IIS 事务日志(凭据未通过):

2014-05-05 15:16:16 10.###.###.## GET /mysite/PrintPreview.aspx RequestId=9851&HideControls=1 80 - 10.###.###.## - - 401 0 0 15
2014-05-05 15:16:16 10.###.###.## GET /mysite/PrintPreview.aspx RequestId=9851&HideControls=1 80 - 10.###.###.## - - 401 1 2148074254 15
2014-05-05 15:16:16 10.###.###.## GET /mysite/PrintPreview.aspx RequestId=9851&HideControls=1 80 - 10.###.###.## - - 401 1 2148074252 0

在最后一行,您会注意到最终事务返回 401.1 Unauthorized 错误

 

(如果你现在还没有猜到,我基本上是在将页面读取到流中,稍后我会使用数据将其写入本地共享上的 html 文件。)

到目前为止,这个过程一直完美无缺。当我们将应用程序移至新服务器时,问题就出现了。

我花了几天时间研究这个问题,但还没有找到原因。重要的是要注意,我是一名开发人员,虽然我对在 IIS 中设置网站有相当多的了解,但我不是服务器管理员,我认为我已经达到了我的能力极限。

我应该如何进一步解决这个问题?任何见解/想法都会有所帮助。如果您有任何问题,请随时提出,我会尽力回答。

【问题讨论】:

    标签: asp.net vb.net iis windows-authentication iis-8


    【解决方案1】:

    经过一番挖掘,我检查了服务器上的事件查看器,在服务器事件查看器中发现了相应的警告:

    分配进程 ID 为 7328 的程序 w3wp.exe 无法使用目标名称 HTTP/codeuat.cmapps.stele.net 在本地进行身份验证。使用的目标名称无效。目标名称应指本地计算机名称之一,例如 DNS 主机名。尝试不同的目标名称。

    在研究了这个错误之后,我实际上发现很多人都有同样的问题。这将我带到一个名为 "BackConnectionHostName"(HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0) 的注册表项,其中缺少我尝试连接的主机名,因此,身份验证失败。

    将主机名添加到条目后,我能够正确通过身份验证,并通过检查 IIS 日志确认了这一点。

    感谢大家的回复。

    【讨论】:

      【解决方案2】:

      您需要指定要使用的身份验证类型,如本答案https://stackoverflow.com/a/1680866/1425531中所述

      至于猜测为什么它在一个服务器上运行而不在另一个服务器上运行:第一台服务器是否只为站点启用了基本身份验证,而另一台服务器上的站点具有 Windows 身份验证 (ntlm)?

      【讨论】:

      • 我试了一下,但无济于事。两台服务器都为网站配置了相同的身份验证设置。我已编辑发布以显示这些设置。检查 IIS 日志后,我还在服务器事件查看器中发现了一个同时出现的警告,其中包含以下消息“分配进程 ID 7328 的程序 w3wp.exe 无法使用目标名称 HTTP/codeuat.cmapps 在本地进行身份验证。 steel.net。使用的目标名称无效。目标名称应引用本地计算机名称之一,例如 DNS 主机名。尝试不同的目标名称。"
      • 我应该注意到,UAT 站点在 2 个不同的服务器之间进行负载平衡,但共享一个公共主机名,而开发服务器则没有。
      • 感谢您的宝贵时间。 +1
      猜你喜欢
      • 1970-01-01
      • 2016-03-20
      • 2018-08-20
      • 1970-01-01
      • 2018-06-19
      • 1970-01-01
      • 1970-01-01
      • 2018-11-10
      • 2018-10-28
      相关资源
      最近更新 更多