2013-08-06 14 views
6

Z mojego czytania o podszywaniu się pod użytkownika w systemie Windows należy poprawnie użyć logonu LOGON32_LOGON_NEW_CREDENTIALS do podszywania się pod użytkownika w bazie danych. Używając ładnego opakowania personalnego Matta Johnsona (pierwotnie opublikowanego pod numerem here, a następnie wypolerowanego pod numerem here), próbowałem to przetestować - oto mój cały program, z wyjątkiem stałych definiujących moją konkretną domenę DOMAIN, USER, PWD i CONN_STRING.Co jest magią podszywania się pod Windows przy pomocy LOGON32_LOGON_NEW_CREDENTIALS?

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(); 
     } 
    } 
} 

Ale to nie działa. Dane wyjściowe raportów mi (mój bazowy zalogowany użytkownik) zarówno z nt_user_name i SUSER_NAME(). (I SQL Profiler zgłasza dokładnie to samo, zapytanie w kodzie jest po prostu wygodnym sposobem zobaczenia, co SQL Profiler mi mówi.)

Jeśli zmienię z LogonType.NewCredentials na LogonType.Interactive (te wyliczenia mają wartości, których można się spodziewać, zdefiniowane na pinvoke.net), to działa - powyższy kod zgłasza prawidłowe podszywanie się do DOMAIN i USER. Ale oznacza to również podszywanie się pod obecną sesję, której nie chcę - chcę tylko podszyć się pod połączenie DB.

myślałem znalazłem jedną usterkę w wyżej - Johnsona personifikacji wrapper twarde kody dostawcy logowania jako LOGON32_PROVIDER_DEFAULT, gdy LogonUser API wyraźnie stwierdza, że ​​typ LOGON32_LOGON_NEW_CREDENTIALS logowania jest obsługiwana tylko przez dostawcę LOGON32_PROVIDER_WINNT50 logowania. Więc złapałem źródło i dodałem parametr pozwalający na określenie wymaganego dostawcy logowania ... ale to nie miało znaczenia.

Więc czego mi brakuje?

+0

Cofanie się o krok od wydania: jeśli zamierzasz zalogować się w instancji serwera DB za pomocą Zintegrowanych zabezpieczeń, nie powinieneś w ogóle polegać na podszywaniu się; w takim przypadku ** 1. ** przy użyciu loginu SQL Server będzie łatwiejszą opcją. Jeśli używasz Zintegrowanego bezpieczeństwa, ** 2. ** po prostu pozwól użytkownikom docelowym zalogować się (ale ogranicz ich prawa do serwera i bazy danych w miarę możliwości); lub (jeszcze lepiej :) ** 3. ** tylko pozwala usłudze uzyskać dostęp do bazy danych i mieć dostęp do aplikacji tylko do usługi, która wykonuje własne uwierzytelnienie i autoryzację. – stakx

+1

Doceniam sugestie @stakx; jednak w tym przypadku nie mam elastyczności do wprowadzania zmian architektonicznych. A poza tym, być może nie będę mógł ponownie zasnąć w nocy, dopóki nie dowiem się, dlaczego powyższe zawodzi :-)! –

+0

Co się stanie, jeśli użyjesz C, aby uzyskać token LOGON32_LOGON_NEW_CREDENTIALS, a następnie uruchomić odrębny proces z tokenem, aby wykonać pracę SQL w twoim imieniu? (Nowy proces może być w języku C#.) –

Odpowiedz

5

Odpowiedź, którą wstydzę się powiedzieć, była tuż przede mną. Stany LogonUser API:

Ten typ logowania pozwala rozmówcy do klonowania obecną żeton i określić nowe poświadczenia dla połączeń wychodzących. Nowa sesja logowania ma ten sam lokalny identyfikator, ale używa innych poświadczeń dla innych połączeń sieciowych. [podkr]

Ale moja baza więc z definicji nie pokaże nowe poświadczenia znajduje się na tym samym komputerze co mój program uruchomiony! Jestem pewien, że podszywanie się będzie działało poprawnie z LOGON32_LOGON_NEW_CREDENTIALS po przeniesieniu bazy danych do innego pola. Westchnienie.