【问题标题】:Impersonation succeeds but database connection fails模拟成功但数据库连接失败
【发布时间】:2013-06-11 15:46:36
【问题描述】:

我有这样的 C# (.NET 4.5) 代码(为演示而简化)用于连接到 SQL Server 2012 数据库:

public static void Test(WindowsIdentity ident)
{
    using (WindowsImpersonationContext ctx = ident.Impersonate())
    {
        using (SqlConnection con = new SqlConnection("Data Source=MyServer;Initial Catalog=MyDatabase;Persist Security Info=False;Integrated Security=SSPI;Network Library=dbmssocn"))
        {
            con.Open();
        }
        ctx.Undo();
    }
}

Open()方法每次都会抛出如下异常:

System.Data.SqlClient.SqlException (0x80131904):网络相关或 建立连接时发生特定于实例的错误 SQL 服务器。服务器未找到或无法访问。核实 实例名称正确且 SQL Server 配置为 允许远程连接。 (提供者:TCP 提供者,错误:0 - 否 可以建立连接,因为目标机器主动拒绝 它。)

模拟成功,因为如果我像这样添加跟踪:

public static void Test(WindowsIdentity ident)
{
    using (TextWriterTraceListener listener = new TextWriterTraceListener(@"C:\temp\trace.log"))
    {
        using (WindowsImpersonationContext ctx = ident.Impersonate())
        {
            listener.WriteLine("Impersonated");
            using (SqlConnection con = new SqlConnection("Data Source=MyServer,MyPort;Initial Catalog=MyDatabase;Persist Security Info=False;Integrated Security=SSPI;Network Library=dbmssocn"))
            {
                listener.WriteLine("About to open connection; WindowsIdentity.GetCurrent().Name = " + WindowsIdentity.GetCurrent().Name);
                con.Open();
            }
            ctx.Undo();
            listener.WriteLine("Impersonation undone");
        }
    }
}

我明白了:

Impersonated
About to open connection; WindowsIdentity.GetCurrent().Name = MyDomain\MyUser

如果我将完全相同的连接字符串放在 .udl 文件中,在同一台机器上的相同“MyDomain\MyUser”帐户下运行它,然后单击测试连接,它会成功。既然是这种情况,我只是不明白问题可能是防火墙或任何类似性质的东西。有谁知道可能出了什么问题?我无权登录数据库服务器本身,因此此时我无法检查其事件日志(等)。

【问题讨论】:

    标签: c# sql-server impersonation


    【解决方案1】:

    匿名登录失败错误意味着kerberos身份验证由于某种原因失败。

    Kerberos 委托(委托是指将您的模拟凭据传递给另一台机器)在理论上相对简单。在实践中,它充满了陷阱,可能是最令人沮丧的故障排除之一。

    在您的情况下,从您的程序的角度来看,完全有可能模拟成功,但它传递给 sql server 的令牌不可用。

    如果您很幸运并且能够接触到非常优秀的网络/系统管理员,那么他们可以帮助您解决问题。
    否则谷歌搜索“sql server kerberos 委托”将为您指明正确的方向。

    这种问题需要大量的反复来解决,并且更适合论坛而不是问答网站。

    【讨论】:

      【解决方案2】:

      您的问题来自连接字符串。连接字符串中的“Network Library = dbmssocn”将使客户端尝试在 UDP 端口 1434 而不是 TCP 端口 1433 上连接 SQL Server。您删除了“Network Library = dbmssocn" 来自应用程序的连接字符串,应用程序将成功连接到 SQL 服务器。

      【讨论】:

      • 感谢您的建议。从连接字符串中删除该段后,我收到以下错误: System.Data.SqlClient.SqlException (0x80131904): Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'。但是,跟踪保持不变,这意味着模拟仍然成功,但由于某种原因它没有被用于尝试连接?
      • 所以这是另一个问题。您应该检查导致使用匿名而不是使用当前登录用户的网络配置。
      • 试试这个 "Data Source=192.162.1.100,1433;Network Library=DBMSSOCN;..." 替换 192.162.1.100 要连接的特定端口是您的计算机端口。
      • 好的,很公平。不幸的是,我对网络一无所知,而且如前所述,我无法访问 SQL Server 机器本身。我会接受你的回答,因为它确实回答了我原来的问题。我将提交另一个问题,看看是否有人可以帮助我解决新问题。非常感谢!
      • 啊,我试试看!
      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 2021-01-19
      • 2011-11-13
      • 2017-07-13
      • 2018-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多