2014-09-03 5 views
13

In meiner WPF-Anwendung möchte ich Administratoren eine Datenbankverbindung mit integrierter Sicherheit für verschiedene andere Benutzer testen können. Also habe ich ein Formular, das es dem Administrator erlaubt, die Domain, den Benutzernamen und das Passwort einzugeben und es dann zu testen. Ich bin in der Lage, sicher bis das Passwort zu behandeln, bis ich LogonUser im advapi32.dll nennen, die eine string passwordSichere Windows Identitätswechsel?

LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle) 

nimmt ich eine Nutzenfunktion geschrieben haben, die die Secure in einen String konvertiert so sicher wie möglich, und dann im rufenden es auf dem Passwort in dem Logonuser Aufruf:

LogonUser(UserName, Domain, Helper.ConvertSafely(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref UserHandle) 

Da die Signatur für Logonuser einen String, es sei denn, Logonuser in seiner Ausführung der richtige Pflege des Passworts nehmen, könnte es auf meinem Call-Stack im Klartext sein noch nach Der Anruf kehrt zurück. Gibt es einen sichereren Weg, sich als ein Benutzer auszugeben, in dem ich vertraulich sein kann, dass das PW die ganze Zeit sicher ist?

Grundsätzlich brauche ich nur WindowsImpersonationContext, aber ich möchte es ohne das Passwort jemals im Klartext erwerben.

+0

Ich habe Ihren Titel bearbeitet. Bitte lesen Sie "[Sollten die Fragen" Tags "in ihren Titeln enthalten?] (Http://meta.stackexchange.com/questions/19190/)", wobei der Konsens "nein, sie sollten nicht" lautet. –

+0

Gute Frage, eigentlich. Wenn Sie sich jedoch ernsthaft Sorgen um die Sicherheit machen, schlage ich vor, dass Sie auch nichttechnische Sicherheitslücken in Betracht ziehen: Ihre Administratoren dürfen keine Kenntnisse über die Kennwörter Ihrer Benutzer haben oder benötigen. Die Tatsache, dass Sie einen Benutzernamen/Passwort-Bildschirm erstellen, legt nahe, dass die Administratoren Anmeldeinformationen eingeben. Das scheint mir sehr falsch zu sein. (Und wenn es nicht Admins sind, sondern die Benutzer selbst, die ihre Anmeldeinformationen ausfüllen, dann "runas" die Anwendung zuerst unter ihrem eigenen Login, und Sie müssen keinen Identitätswechsel durchführen.) – stakx

+0

Wird nicht das ursprüngliche Formular-Eingabefeld verwendet sowieso eine reguläre Zeichenfolge? Möglicherweise möchten Sie auch Ihren 'LogonUser'-Code mit meiner [SimpleImpersonation] (https://github.com/mj1856/SimpleImpersonation) -Bibliothek vereinfachen, wie [hier] beschrieben (http://stackoverflow.com/a/7250145)/634824). Obwohl ich 'SecureString' dort auch nicht verwende. –

Antwort

4

Wenn der Benutzer, den Sie ausgeben möchten, bereits auf dem Rechner angemeldet ist (zum Beispiel in einer anderen Sitzung), hier ist eine Antwort: Is it possible for a Windows service impersonate a user without a password?

Wenn er nicht, werden Sie ein Passwort zu Logonuser bieten müssen. Und dieses Passwort muss mindestens eine kleine Menge Zeit haben, so wie es im Speicher ist, weil LogonUser so definiert ist. Beachten Sie, dass nicht alle Auth-Pakete Passwörter benötigen (wie Biometrie oder Smartcard: Windows Authentication Overview).

Also, wenn Sie wirklich Identitätswechsel wollen, irgendwo müssen Sie ein Passwort herumreichen. Verwenden Sie in diesem Fall den Code der postlagerkarte von Microsoft: Marshal.SecureStringToGlobalAllocUnicode Method sample code

Sie können nicht viel mehr tun.

6

In Ihrer verwalteten Anwendung können Sie die SecureString-Klasse verwenden, um mit vertraulichen Informationen umzugehen. In der Regel ist es nicht erforderlich, einen eigenen sicheren String-Mechanismus zu erstellen.

Kurz bevor Sie in LogonUser einpinnen, übergeben Sie die unverwaltete Kopie von das SecureString-Passwort. Sie verwenden hierzu die Methode Marshal.SecureStringToGlobalAllocUnicode. Daher gibt es in Ihrer App-Domain nie ein verwaltetes Objekt, das das Kennwort darstellt.

Sie finden Beispielcode in this Artikel.

Wenn Sie noch mehr Sicherheit benötigen, würde ich vorschlagen, direkte Datenbankverbindung von Ihren wpf-Clients zu verbieten. Sie können eine mittlere Stufe einführen. Die Sicherheit wird somit von den Clients auf diesen einen Server verlagert. Die Kommunikation zwischen Client und App-Server ist verschlüsselt und nur der App-Server spricht mit der Datenbank.

+0

Dies ist genau das, was ich tue, ich bin nur besorgt, dass der LogonUser-Aufruf das ungesicherte Passwort auf dem Stapel hinterlassen wird, das nicht in meinen Händen ist. – user1336827

+0

ja du hast Recht. Vielleicht möchten Sie es in Ihrer Frage deutlicher machen. Es ist immer möglich, einen Haltepunkt im API LogonUser-Eintrag festzulegen und den Call Stack auszugeben. Die Frage bezieht sich also eher auf die native LogonUser-Funktion. – Postlagerkarte

+0

Ich bin mir nicht sicher, ob ich die Frage viel klarer machen kann, ich habe es versucht. Aber die Sorge ist mit dem nicht verwalteten Code LogonUser, und wenn es eine sicherere Methode gibt, einen WindowsImpersonationContext zu erwerben, ohne sich darum kümmern zu müssen, wie der nicht verwaltete Code das Passwort verarbeitet, scheint es es im Klartext zu verwenden. – user1336827

1

Update:

Sie könnten eine verschlüsselte app.config implementieren. verschiedene Ansätze tun dies durch Sie können:

So, wie dies funktionieren würde, ist, wenn ein Administrator die Berechtigungsnachweise fügt würden Sie entschlüsseln die app.config ändern Sie den Schlüssel/Wert mit den neuen Anmeldeinformationen. Sobald es eingefügt ist, verschlüsselt es die Konfigurationsdatei erneut.

So ist es minimal ausgesetzt, aber auch die Daten werden durch Kapselung eingefügt, die hilft, es auch zu verbergen.

Dies ist ein Ansatz, obwohl ein SecureString funktioniert, erwartet es eine char[]. Was in einigen Fällen nicht ideal sein kann, wenn es über die advapi32.dll Schnittstelle angeschlossen wird.

+0

Ich bin verwirrt. Wie werden die verschlüsselten Anmeldeinformationen von der Konfiguration an LogonUser übergeben? –

+0

die Sicherheit in meinem Code ist kein Problem, das Passwort wird in einem SecureString gespeichert, es ist, wenn ich den nicht verwalteten Code LogonUser das Passwort im Klartext verwendet. – user1336827

+0

@ user1336827 Also der nicht verwaltete Code ruft es tatsächlich in Nur-Text auf? – Greg

Verwandte Themen