2014-11-25 50 views
1

我在從代碼(C#)與ASP.NET中的模擬故障和使用SQL Server Express:ASP.NET模擬和連接SQL Server Express的用戶

我能成功地冒充並連接到SQL Server,但執行SELECT CURRENT_USER返回guest而不是TestUser_001

注意:我嘗試使用LOGON32_LOGON_NETWORK_CLEARTEXTLOGON32_LOGON_INTERACTIVE聯繫時嘗試模仿,致電LogonUser時 - 結果保持不變。我正在執行此模擬代碼的帳戶已設置Act as part of the operating system。在IIS Express下測試(Visual Studio 2013中的F5)。我從來沒有以交互方式登錄爲TestUser_001並連接到SQL Server Express實例 - 沒有MY_DOMAIN\TestUser_001Security\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(); 
    } 
} 
+0

什麼是ImpersonationHelper?構造函數是否已經執行模擬,或者您是否需要先調用某種方法? – Heinzi 2014-11-25 12:55:15

+0

'ImpersonationHelper'已經模仿。在連接到SQL Express之前調用'ImpersonationHelper'後,'WindowsIdentity.GetCurrent()。Name'返回'My_DOMAIN \ TestUser_001'。 – vladeck 2014-11-25 13:04:52

+1

什麼'SELECT SUSER_SNAME();'return? – 2014-11-25 13:16:09

回答

1

謝謝Dan Guzman - SQL Server MVP和所有其他與這個問題有幫助。我想我將這個標記爲一個答案,因爲模擬工作和正確的用戶由SQL Server報告。