我在從代碼(C#)與ASP.NET中的模擬故障和使用SQL Server Express:ASP.NET模擬和連接SQL Server Express的用戶
我能成功地冒充並連接到SQL Server,但執行SELECT CURRENT_USER
返回guest
而不是TestUser_001
。
注意:我嘗試使用LOGON32_LOGON_NETWORK_CLEARTEXT
與LOGON32_LOGON_INTERACTIVE
聯繫時嘗試模仿,致電LogonUser
時 - 結果保持不變。我正在執行此模擬代碼的帳戶已設置Act as part of the operating system
。在IIS Express下測試(Visual Studio 2013中的F5)。我從來沒有以交互方式登錄爲TestUser_001
並連接到SQL Server Express實例 - 沒有MY_DOMAIN\TestUser_001
在Security\Logins
下 - 想要在使用代碼時自動發生這種情況。
using (var impersonation = new ImpersonationHelper("TestUser_001", "MY_DOMAIN", "pass"))
{
using (var conn = new SqlConnection(@"Data Source=MY_DOMAIN\SQLEXPRESS;Integrated Security=True;"))
{
conn.Open();
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT CURRENT_USER";
var result = cmd.ExecuteScalar();
}
}
}
這裏是簡陋ImpersonationHelper
實現:
public class ImpersonationHelper : IDisposable
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
public const int LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll")]
public static extern int LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int DuplicateToken(
IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool CloseHandle(IntPtr handle);
private readonly WindowsImpersonationContext impersonationContext_;
public ImpersonationHelper(string username, string domain, string password)
{
var token = IntPtr.Zero;
var token_duplicate = IntPtr.Zero;
if (RevertToSelf())
{
if (LogonUser(username, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if (DuplicateToken(token, 2, ref token_duplicate) != 0)
{
var temp_windows_identity = new WindowsIdentity(token_duplicate);
impersonationContext_ = temp_windows_identity.Impersonate();
if (impersonationContext_ != null)
{
CloseHandle(token);
CloseHandle(token_duplicate);
return;
}
}
}
}
if (token != IntPtr.Zero)
CloseHandle(token);
if (token_duplicate != IntPtr.Zero)
CloseHandle(token_duplicate);
throw new Exception(string.Format("Unable to impersonate as {0}\\{1}.", username, domain));
}
public void Dispose()
{
impersonationContext_.Undo();
}
}
什麼是ImpersonationHelper?構造函數是否已經執行模擬,或者您是否需要先調用某種方法? – Heinzi 2014-11-25 12:55:15
'ImpersonationHelper'已經模仿。在連接到SQL Express之前調用'ImpersonationHelper'後,'WindowsIdentity.GetCurrent()。Name'返回'My_DOMAIN \ TestUser_001'。 – vladeck 2014-11-25 13:04:52
什麼'SELECT SUSER_SNAME();'return? – 2014-11-25 13:16:09