"Identitätswechsel" im .NET-Bereich bedeutet im Allgemeinen, dass Code unter einem bestimmten Benutzerkonto ausgeführt wird. Es ist ein etwas anderes Konzept, als über einen Benutzernamen und ein Passwort auf dieses Benutzerkonto zuzugreifen, obwohl diese beiden Ideen häufig zusammenpassen. Ich werde sie beide beschreiben und dann erklären, wie ich meine SimpleImpersonation- Bibliothek verwende, die sie intern verwendet.
Identitätswechsel
Die APIs für den Identitätswechsel werden in .NET über den System.Security.Principal
Namespace bereitgestellt :
Im Allgemeinen sollte neuerer Code (.NET 4.6+, .NET Core usw.) verwendet werden WindowsIdentity.RunImpersonated
, der ein Handle für das Token des Benutzerkontos akzeptiert und dann entweder ein Action
oder Func<T>
für die Ausführung des Codes.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
});
oder
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
return result;
});
Älterer Code verwendete die WindowsIdentity.Impersonate
Methode zum Abrufen eines WindowsImpersonationContext
Objekts. Dieses Objekt wird implementiert IDisposable
und sollte daher im Allgemeinen von einem using
Block aus aufgerufen werden .
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
// do whatever you want as this user.
}
Diese API ist zwar noch in .NET Framework vorhanden, sollte jedoch generell vermieden werden und ist in .NET Core oder .NET Standard nicht verfügbar.
Zugriff auf das Benutzerkonto
Die API für die Verwendung eines Benutzernamens und eines Kennworts für den Zugriff auf ein Benutzerkonto in Windows lautet LogonUser
- eine native Win32-API. Derzeit gibt es keine integrierte .NET-API zum Aufrufen, daher muss auf P / Invoke zurückgegriffen werden.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
Dies ist die grundlegende Anrufdefinition, es gibt jedoch noch viel mehr zu beachten, um sie tatsächlich in der Produktion zu verwenden:
- Erhalten eines Handles mit dem "sicheren" Zugriffsmuster.
- Schließen Sie die nativen Handles entsprechend
- CAS-Vertrauensstufen (Code Access Security) (nur in .NET Framework)
- Bestehen,
SecureString
wenn Sie einen sicher über Benutzertastenanschläge sammeln können.
Die Menge an Code, die geschrieben werden muss, um all dies zu veranschaulichen, übersteigt IMHO die Anforderungen einer StackOverflow-Antwort.
Ein kombinierter und einfacherer Ansatz
Anstatt all dies selbst zu schreiben, sollten Sie meine SimpleImpersonation- Bibliothek verwenden, die Identitätswechsel und Benutzerzugriff in einer einzigen API kombiniert. Es funktioniert sowohl in modernen als auch in älteren Codebasen mit derselben einfachen API:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
});
oder
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
return something;
});
Beachten Sie, dass es der WindowsIdentity.RunImpersonated
API sehr ähnlich ist , jedoch keine Kenntnisse über Token-Handles erfordert.
Dies ist die API ab Version 3.0.0. Weitere Informationen finden Sie in der Projekt-Readme-Datei. Beachten Sie auch, dass eine frühere Version der Bibliothek eine API mit dem IDisposable
Muster verwendet hat, ähnlich wie WindowsIdentity.Impersonate
. Die neuere Version ist viel sicherer und beide werden weiterhin intern verwendet.