【问题标题】:Intermittent '401: Unauthorized' exceptions from server来自服务器的间歇性“401:未经授权”异常
【发布时间】:2011-11-16 06:25:36
【问题描述】:

我有一个托管在集群环境中的 Web 服务。调用此服务的 Web 应用程序也托管在集群环境中,但位于不同的 IIS6 服务器集上。因此,应用程序服务器是 appserv1 和 appserv2,服务服务器是 svcserv1 和 svcserv2。我们不控制访问哪些服务器,因为我们通常将它们分别称为 appserv 或 svcserv。
该服务是 WCF 服务,但已创建为与 .Net 2.0 Web 服务框架兼容。应用程序在运行时运行良好,但可能有 > 35% 的时间服务响应 Exception: The request failed with HTTP status 401: Unauthorized. 错误。

我看到其他人建议直接设置凭据,我的应用程序正在执行以下操作。

Dim cc As New CredentialCache()
Dim service As WCFServiceRef.Reports

service = New WCFServiceRef.Reports

service.Url = serviceURL
cc.Add(New Uri(service.Url), "Negotiate", New NetworkCredential("username", "password"))
service.Credentials = cc

reportData = service.GenerateReport(reportid, True, parameters, "PDF", Environment)

我还尝试通过更改参考 URL 以绕过负载管理器并直接访问服务器的域名来直接访问各个服务器,但这并没有任何区别。

我还看到了this MSDN KB 文章,但由于我无法直接访问服务器配置(而且很难进行任何更改),我想确保我无法从应用端。请注意,服务器已配置为 Windows 身份验证,不允许匿名访问。

谢谢!

【问题讨论】:

    标签: .net wcf iis-6 wcf-security windows-authentication


    【解决方案1】:

    这在很大程度上取决于您的身份验证尝试是使用 Kerberos 还是回退到 NTLM。我建议使用像 Fiddler 这样的工具来捕获从您的应用服务器发送的数据包,以验证正在使用的身份验证协议。

    如果您发现自己在使用 Kerberos,可以尝试以下方法:

    1. 让您的管理员在两台服务器上启用 Kerberos 错误日志记录,然后重新尝试身份验证并检查事件日志中的任何 Kerberos 错误。见http://support.microsoft.com/kb/262177
    2. 检查为您的服务注册的 SPN - 假设您的服务的 FQDN 是 myservice.prd.ad 您需要两个 SPN - 如果您的 IIS6 应用程序池未作为服务运行,则它们应该注册到托管您的服务的服务器帐户,否则应注册到服务帐户:
      • HTTP/MYSERVICE.PRD.AD
      • HTTP/MYSERVICE
    3. 还要确保为您的服务注册的任何 DNS 条目都是 A(主机名)记录,而不是 CNAME(别名)记录。我在我工作过的环境中遇到了一些问题,当 CNAME 记录用于 DNS 时,XP/2003 机器试图为错误的 SPN 获取 Kerberos 票证(而 Windows 7/2008 机器没有)。
    4. 您也可以尝试在您的服务服务器上安装 DelegConfig,它非常适合解决人们在使用 Kerberos 身份验证时遇到的最常见问题。见http://www.iis.net/community/default.aspx?tabid=34&g=6&i=1887

    希望这会有所帮助。如果您使用的是 NTLM,那么我很遗憾没有太多想法,因为我习惯于在仅 Kerberos 的环境中工作。

    【讨论】:

    • 谢谢。你给了我很多调查。我将花一些时间研究并跟进我的发现。我目前正在调查 SPN 注册,因为我没有在我的 .config 文件中设置这些值。
    • 如果我使用模拟运行服务,这是否会影响与上述 #2 相关的运行服务的帐户(用于设置 SPN/UPN)?
    • 我刚刚重新阅读了您的部分问题,并注意到您提到您的服务服务器正在集群中运行或负载平衡 - 在这种情况下,您绝对应该将 SPN 注册到服务帐户并拥有作为该服务帐户运行的 IIS6 应用程序池。我不是 100% 确定模拟将如何影响这一点,但我没有看到任何其他方式(如在负载平衡/集群环境中,如果您将 SPN 注册到计算机帐户 IIS 将不知道如何解密Kerberos 票证,因为它无法判断请求实际发送到哪台机器)。
    • 我们观察了单个服务器 (svcserv1) 上的 Kerberos 日志,发现模拟用户的失败实际上将“目标服务器名称”列为 svcserv2,而所有成功都列为 svcserv1。仅供参考,失败响应来自用户“NT AUTHORITY\SYSTEM”。我想你搞定了。现在的问题是如何在集群环境中设置 SPN。嘿,继续搜索。
    • 根据我们的讨论,我在这里添加了对这个问题的跟进:stackoverflow.com/questions/7422194/…
    【解决方案2】:

    首先检查每台机器上的 IIS 日志,看看 401 错误是否来自单台机器。

    接下来要检查的是 401 是否与特定 url 相关。

    【讨论】:

      【解决方案3】:

      要考虑的另一件事:

      您需要粘性会话吗? 是否存在过于频繁回收的服务器?

      您可能会得到 401 的原因有很多,所以您只需要四处寻找并找出发生了什么。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-13
        • 2013-11-28
        • 1970-01-01
        • 2012-11-11
        • 2015-11-13
        • 2017-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多