2013-08-12 3 views
9

In meinem Weg, die Nuancen der Benutzeridentitätswechsel in Windows zu meistern, hatte ich zuerst ein Problem über Identitätswechsel zu einer entfernten Datenbank überhaupt auftreten (siehe this SO question), aber ich habe das schließlich herausgefunden. Meine nächste Hürde ist Rückgängigmachen/Abbrechen/Zurücksetzen (wählen Sie Ihr Lieblingsverb) Identitätswechsel.Windows-Identitätswechsel: Ein Fehler in der Salbe

Ich habe ein paar verschiedene Identitätswechsel Bibliotheken versucht, die mir glaubwürdig erscheinen:

Die Ergebnisse Harding mit beiden Bibliotheken identisch sind. Bewährte Methoden schreiben die Verwendung des Anmeldetyps LOGON32_LOGON_NEW_CREDENTIALS (siehe Windows-API LogonUser function) für eine ferne DB-Verbindung vor. Wenn ich das hier tun ist, was mein Beispielcode erzeugt:

// SCENARIO A 
BEGIN impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\ImpersonatedUser 
END impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\ImpersonatedUser << NOT EXPECTED HERE!! 

Die einzige Abhilfe, die ich gefunden habe, ist den LOGON32_LOGON_INTERACTIVE Anmeldetyp verwendet wird und dann bekomme ich diese:

// SCENARIO B 
BEGIN impersonation. 
Local user = MyDomain\ImpersonatedUser << EXPECTED, BUT NOT WANTED! 
DB reports: MyDomain\ImpersonatedUser 
END impersonation. 
Local user = MyDomain\MyUser 
DB reports: MyDomain\MyUser 

Aus der lapidaren Beschreibung die WindowsImpersonationContext.Undo Methode scheint es sollte wie in Szenario A gearbeitet haben.

Ist es möglich, mithilfe der Anmeldetyp LOGON32_LOGON_NEW_CREDENTIALS wiederherstellen?

+0

Schließen und öffnen Sie die Verbindung zur Datenbank. Die Datenbank erhält keine Benachrichtigung, wenn Sie Identitätswechselebenen ändern. Ich kann nur vermuten, dass der Datenbank-Client in Szenario B automatisch eine neue Verbindung herstellt. –

+0

Danke für den Kommentar, @ HarryJohnston; Ich hätte sagen sollen, dass ich tatsächlich die SQL-Verbindung geschlossen und eine neue gestartet habe. –

+0

Vielleicht speichert der Datenbankclient die SQL-Verbindung oder wahrscheinlicher die zugrunde liegende Netzwerkverbindung (eine Named Pipe?). Ihre beste Option ist wahrscheinlich, einen Unterprozess (im Kontext des neuen Tokens) zu starten, um die imitierte Datenbankverbindung für Sie auszuführen. –

Antwort

6

Dank der Eingabe von Harry Johnston (in den Kommentaren an die Frage) und Phil Harding (in separater Kommunikation) konnte ich feststellen, dass SQL Server connection pooling der Schuldige hier war. Da das Pooling durch die Eindeutigkeit der Verbindungszeichenfolge bestimmt wird, beobachtete ich durch leichtes Variieren der Verbindungszeichenfolge (z. B. das Umkehren der Reihenfolge der Parameter innerhalb oder sogar das Hinzufügen eines Leerzeichens am Ende) das erwartete Verhalten.

===== TEST WITH SAME CONN STRING: True 
BEGIN impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser 
END impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser <<<<< still impersonating !! 

===== TEST WITH SAME CONN STRING: False 
BEGIN impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\testuser 
END impersonation 
Local user: MyDomain\msorens 
DB reports: MyDomain\msorens <<<<< this is what I wanted to get 
+0

Etwas anderes muss bei der Arbeit sein. In diesem Link, den Sie zur Verfügung gestellt haben, heißt es: "Verbindungen werden durch Verbindungszeichenfolge in Pools aufgeteilt, und durch Windows-Identität, wenn integrierte Sicherheit verwendet wird.". Kannst du etwas Code zeigen? –

+1

Meine Interpretation in dieser Aussage ist, dass "Windows-Identität" bedeutet, was "System.Security.Principal.WindowsIdentity.GetCurrent(). Name" zurückgibt (was ich in meiner Antwort oben als "Lokaler Benutzer" berichte). Das heißt, wenn LOGON32_LOGON_NEW_CREDENTIALS verwendet wird, ändert _not_ nicht die Windows-Identität und taucht daher in demselben Pool ein. Sind Sie einverstanden? –

+0

Ich glaube nicht, dass das der Fall ist, aber ich werde ein paar Tests machen und es herausfinden. Es ist einfach genug, die Anmeldeinformationen in SQL Profiler zu sehen. –

5

Ich grub in die Interna der Connection-Pooling, und es stellt sich heraus, dass Windows-Anmeldeinformationen nicht einen Teil des Verbindungs-Pooling Schlüssel in Betracht gezogen werden. Nur SQL-Logins würden berücksichtigt.

Wenn also eine Verbindung verfügbar ist, die unter Benutzer A geöffnet wurde und Sie sich jetzt als Benutzer B ausgeben, wird sie weiterhin verwendet und SQL wird Sie als Benutzer A sehen. Das Umgekehrte ist auch wahr.

Der Ansatz, die Verbindungszeichenfolge für die zwei verschiedenen Benutzer leicht zu ändern, ist in Ordnung. Sie können dies tun, wenn Sie einen "normalen" Benutzer haben und Sie sich dann für einen "erhöhten" Benutzer ausgeben müssen. Natürlich wollen Sie keine andere Zeichenfolge für jeder Benutzer Ihrer Anwendung - sonst können Sie auch Verbindungspooling vollständig deaktivieren.

Wenn Sie Ihre Verbindungszeichenfolge optimieren, können Sie den impersonierten Benutzernamen an die Felder Application Name oder Workstation ID anhängen. Dies hätte den Vorteil, dass für jeden imitierten Benutzer ein eigener Pool eingerichtet wird.