【问题标题】:Integrated Windows authentication in IIS causing ADO.NET failureIIS 中的集成 Windows 身份验证导致 ADO.NET 失败
【发布时间】:2011-02-22 00:01:40
【问题描述】:

我们有一个在 IIS 下运行的 .NET 3.5 Web 服务(不是 WCF)。它必须使用identity impersonate="true" 和集成Windows 身份验证才能对第三方软件进行身份验证。此外,它使用 ADO.NET 和 SQL Server 身份验证(在连接字符串中指定固定的用户 ID 和密码)连接到 SQL Server 数据库。

在数据库从 SQL Server A 移动到 SQL Server B 之前一切正常。(两者都与 Web 服务器不一样。)然后 Web 服务将抛出以下异常:

网络相关或 发生特定于实例的错误 建立与 SQL 的连接 服务器。找不到服务器或 无法访问。验证 实例名称正确且该 SQL 服务器配置为允许远程 连接。 (提供者:命名管道 提供者,错误:40 - 无法打开 连接到 SQL Server)

此错误在 Web.config 中的身份模拟为 true 时发生。

同样,连接字符串没有改变,它指定了用户。我已经测试了连接字符串,它在模拟帐户和服务帐户下(以及来自远程计算机和服务器)都有效。

需要进行哪些更改才能使其与模拟一起使用?

编辑:

Remus Rusanu 为我们指明了正确的方向。它归结为 Kerberos - 没有为新服务器设置 SPN。另见asp.net via kerberos integrated windows authentication to sql server。谢谢!

【问题讨论】:

    标签: sql-server web-services ado.net asmx impersonation


    【解决方案1】:

    当使用模拟和访问不同主机上的资源时,会发生委派(外行人称之为“两跳”)。由于默认情况下限制委派,因此除非明确启用限制委派,否则身份验证将失败。

    但是等等,你说,我使用 SQL 身份验证,而 SQL 身份验证不是 NTLM/Kerberos 的“资源”。没错,我说,但您也使用 NAMED PIPES 并且命名管道 NTLM/Kerberos 资源,因此委托确实发生。

    请参阅How to: Configure Client Protocols 以确保 SQL Server 正在侦听 TCP,Configuring Client Network Protocols 以了解如何强制客户端选择特定协议(即,不要先尝试命名管道)。您也可以通过在连接字符串中的服务器名称前面简单地附加 tcp: 来强制 TCP。

    【讨论】:

    • 如果我附加“tcp:”,我得到:“(提供者:TCP 提供者,错误:0 - 无法建立连接,因为目标机器主动拒绝它。)”我在本地尝试了这个机器,如果我关闭“tcp:”,它将在哪里工作。
    • 您的服务器未配置为侦听 TCP,或者未侦听默认端口
    【解决方案2】:

    您是否在 Web 服务本身中使用模拟?

    Web 服务中的模拟在与 IIS 不同的层上运行。要从客户端到 Web 服务,您可以关闭 identity=impersonate 并从 ServiceSecurityContext 获取用户令牌,即使启用了匿名模式。

    要在 Web 服务中模拟该令牌,请从 ServiceSecurityContext 获取 WindowsCredential 并在 using 语句中调用 credential.Impersonate() 方法,将与数据库的连接放置在 using 块内。

    public class HelloService : IHelloService
    {
        [OperationBehavior]
        public string Hello(string message)
        {
            WindowsIdentity callerWindowsIdentity =
            ServiceSecurityContext.Current.WindowsIdentity;
            if (callerWindowsIdentity == null)
            {
                throw new InvalidOperationException
               ("The caller cannot be mapped to a WindowsIdentity");
            }
            using (callerWindowsIdentity.Impersonate())
            {
                // Access a file as the caller.
            }
            return "Hello";
        }
    }
    

    此外,如果您在流程中需要另一条腿(即后端服务在另一台服务器上),您将需要使用委托来传播凭据。您也可以以声明方式执行此操作。详情请看这篇文章:http://msdn.microsoft.com/en-us/library/ms730088.aspx

    【讨论】:

    • 我正在使用通过 IIS 设置的模拟和该服务的 Web.config。虽然您的技术可能允许我们在调用第三方软件时而不是在调用 ADO.NET 时进行模拟,但它会使代码(在移动 SQL Server 之前工作)显着复杂化。我们也没有使用 WCF,因此委托链接似乎不相关。
    • 我不知道您没有使用 WCF,或者 SQL 服务器从未在同一个机器上。我发布的代码是 WCF 所需的,因为模拟不是通过 IIS 完成的。很抱歉造成混乱,感谢您的澄清
    • 谢谢 - 我在原始帖子中添加了注释以澄清。
    【解决方案3】:

    由于它在 SQL Server 在同一个盒子上时工作,它可以连接到事务。

    可能是它正在尝试使用 MSDTC,而被冒充的用户缺少某些权限。

    您可以尝试的另一件事是使用您尝试模拟的用户登录到 Web 服务器,然后查看是否可以连接到 sql 服务器。

    【讨论】:

    • 我编辑了问题以澄清它。 SQL Server(旧的或新的)都没有与 Web 服务器在同一个盒子上。
    【解决方案4】:

    如果委派是您的问题,请参阅本文以启用约束委派 http://msdn.microsoft.com/en-us/library/ms730088.aspx

    转到最底部以了解如何为约束委派设置帐户。我知道这是一篇 WCF 文章,但是设置帐户以使用委托的过程应该是相同的。

    更多详情,请点击此处 http://technet.microsoft.com/en-us/library/cc739587(WS.10).aspx

    或者,让您的 SQL 服务器启用 TCP 访问并以这种方式访问​​它,正如 Remus 解释的那样。

    【讨论】:

      猜你喜欢
      • 2012-09-23
      • 2015-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多