使用LOGON32_LOGON_NEW_CREDENTIALS对Windows进行冒充有什么魔力?

从我阅读Windows上的用户模拟中,应该正确使用LOGON32_LOGON_NEW_CREDENTIALSlogintypes来模拟用户到数据库。 使用马特约翰逊的好模拟包装(最初张贴在这里 ,然后打磨在这里 ),我试图testing这个 – 这是我的整个程序,除了常量定义我的特定DOMAIN,USER,PWD和CONN_STRING。

using System; using System.Data.SqlClient; using SimpleImpersonation; namespace ImpersonationDemo { class Program { private static SqlConnection _connection; static void Main(string[] args) { using (Impersonation.LogonUser( DOMAIN, USER, PWD, LogonType.NewCredentials)) { GetOpenConnection(); CheckDbCredentials(); CloseConnection(); } Console.WriteLine("Press return to exit"); Console.ReadLine(); } private static void CheckDbCredentials() { using ( var command = new SqlCommand( "SELECT nt_user_name, SUSER_SNAME() " +"FROM sys.dm_exec_sessions WHERE session_id = @@SPID", _connection)) { using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { Console.WriteLine("{0}, {1}", reader.GetString(0), reader.GetString(1)); } } } } private static void GetOpenConnection() { _connection = new SqlConnection(CONN_STRING); _connection.Open(); } private static void CloseConnection() { _connection.Close(); } } } 

但是这不起作用。 输出从nt_user_nameSUSER_NAME()报告 (我的基础login用户SUSER_NAME() 。 (和SQL Profiler报告完全一样的东西;代码中的查询只是查看SQL Profiler告诉我的简单方法。

如果我从LogonType.NewCredentials更改为LogonType.Interactive (这些枚举具有您所期望的值,就像在pinvoke.net上定义的那样 ),那么它确实有效 – 上面的代码报告了正确的DOMAIN和USER模拟。 但这也意味着当前会话正在模拟,我不想 – 我只想要数据库连接被模拟。

我以为我在上面发现一个小故障 – 当LogonUser API清楚地声明LOGON32_LOGON_NEW_CREDENTIALSlogintypes仅由LOGON32_PROVIDER_WINNT50login提供程序支持时,约翰逊的模拟包装硬编码login提供程序为LOGON32_PROVIDER_DEFAULT 。 所以我抓住了源代码,并添加了一个参数,以允许指定必要的login提供程序…但没有任何区别。

那么我错过了什么?

我惭愧地说,我的回答一直在我面前。 LogonUser API指出:

此登录类型允许调用方克隆其当前令牌并指定出站连接的新凭据。 新的登录会话具有相同的本地标识符,但对其他网络连接使用不同的凭据。 [强调我的]

但是我的数据库与我的运行程序在同一台机器上,所以根据定义,它不会显示新的凭据! 我有信心,一旦将我的数据库移动到不同的方框,模拟将与LOGON32_LOGON_NEW_CREDENTIALS正常工作。 叹。