根据我对Windows上用户模拟的阅读,应该正确地使用LOGON32_LOGON_NEW_CREDENTIALS登录类型来模拟用户到数据库。使用Matt的漂亮的模拟包装器(最初发布了这里,然后改进了这里),我试着测试它--这是我的整个程序,除了定义特定域、用户、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_name和SUSER_NAME()的me (我的底层登录用户)。( simply报告的内容完全相同;代码中的查询只是查看simply告诉我的内容的一种方便的方法。)
如果我从LogonType.NewCredentials更改为LogonType.Interactive (这些枚举具有您期望的值,就像在pinvoke.net上定义的那样),那么它确实工作--上面的代码报告了正确的域和用户模拟。但这也意味着正在模拟当前会话,而我不希望--我只希望模拟DB连接。
我想我在上面--约翰逊的模拟包装器中发现了一个故障--将登录提供程序硬编码为LOGON32_PROVIDER_DEFAULT,当LogonUser API清楚地声明LOGON32_LOGON_NEW_CREDENTIALS登录类型仅由LOGON32_PROVIDER_WINNT50登录提供程序支持时。因此,我抓取源代码并添加了一个参数,允许指定必要的登录提供程序.但这没什么区别。
那我错过了什么?
发布于 2013-08-10 22:57:10
我惭愧地说,答案一直就在我面前。LogonUser API声明:
此登录类型允许调用方克隆其当前令牌,并为出站连接指定新凭据。新的登录会话具有相同的本地标识符,但对其他网络连接使用不同的凭据。重点雷
但是我的数据库和我运行的程序在同一台机器上,所以根据定义,它不会显示新的凭据!我相信,一旦我将我的数据库移到另一个框中,模拟将正确地与LOGON32_LOGON_NEW_CREDENTIALS一起工作。叹一口气。
https://stackoverflow.com/questions/18091923
复制相似问题