模拟成功但数据库连接失败

时间:2013-06-14 21:59:53

标签: c# sql-server impersonation

我有这样的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 Server。服务器未找到或无法访问。校验   实例名称正确且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”帐户下运行它,然后单击“测试连接”,它会成功。既然如此,我只是看不出问题如何成为防火墙或任何性质的问题。有谁知道会出现什么问题?我没有登录数据库服务器本身的权限,所以此时我无法检查其事件日志(等)。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

Kerberos委派(委托是将您的模拟凭据传递给其他计算机)理论上相对简单。在实践中,它充满了陷阱,可能是最令人沮丧的事情之一。

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

如果您很幸运并且可以访问一个非常好的网络/系统管理员,那么他们可以帮助您排除故障。
否则谷歌搜索“sql server kerberos delegation”会指出你正确的方向。

这是一个需要大量来回解决的问题,比Q& A网站更适合论坛。