IIS中的集成Windows身份验证导致ADO.NET失败

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

一切正常,直到数据库从SQL Server A移动到SQL Server B.(两者都不同于Web服务器 . )然后Web服务将抛出以下异常:

Build 与SQL Server的连接时发生与网络相关或特定于实例的错误 . 服务器未找到或无法访问 . 验证实例名称是否正确,以及SQL Server是否配置为允许远程连接 . (提供者:命名管道提供程序,错误:40 - 无法打开与SQL Server的连接)

如果Web.config中的identity impersonate为true,则会发生此错误 only .

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

需要改变什么才能使其与模仿一起工作?

EDIT:

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

回答(4)

3 years ago

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

但是等等,你说,我使用SQL身份验证和SQL身份验证不是NTLM / Kerberos 'resource' . 是的,我说,但你也使用 NAMED PIPES 并命名管道 are 一个NTLM / Kerberos资源,因此委托会发生 .

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

3 years ago

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

Web服务中的模拟操作在与IIS不同的层上运行 . 要从客户端到Web服务,您可以使用identity = impersonate off并从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

3 years ago

由于它在SQL Server位于同一个盒子上时起作用,因此它可以连接到事务 .

可能是它正在尝试使用MSDTC,并且模拟用户缺少某些权限 .

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

3 years ago

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

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

更多细节,请到这里http://technet.microsoft.com/en-us/library/cc739587(WS.10).aspx

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