«L'emprunt d'identité» dans l'espace .NET signifie généralement exécuter du code sous un compte d'utilisateur spécifique. C'est un concept quelque peu différent de celui d'accéder à ce compte utilisateur via un nom d'utilisateur et un mot de passe, bien que ces deux idées se combinent fréquemment. Je vais les décrire tous les deux, puis expliquer comment utiliser ma bibliothèque SimpleImpersonation , qui les utilise en interne.
Imitation
Les API pour l'emprunt d'identité sont fournies dans .NET via l' System.Security.Principal
espace de noms:
Le code plus récent (.NET 4.6+, .NET Core, etc.) doit généralement utiliser WindowsIdentity.RunImpersonated
, qui accepte un handle vers le jeton du compte d'utilisateur, puis un Action
ou Func<T>
pour le code à exécuter.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
});
ou
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
return result;
});
Un code plus ancien utilisait la WindowsIdentity.Impersonate
méthode pour récupérer un WindowsImpersonationContext
objet. Cet objet implémente IDisposable
, doit donc généralement être appelé à partir d'un using
bloc.
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
// do whatever you want as this user.
}
Bien que cette API existe toujours dans .NET Framework, elle doit généralement être évitée et n'est pas disponible dans .NET Core ou .NET Standard.
Accéder au compte utilisateur
L'API permettant d'utiliser un nom d'utilisateur et un mot de passe pour accéder à un compte d'utilisateur dans Windows est LogonUser
- qui est une API native Win32. Il n'existe actuellement aucune API .NET intégrée pour l'appeler, il faut donc recourir à P / Invoke.
[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);
Ceci est la définition de base de l'appel, mais il y a beaucoup plus à considérer pour l'utiliser en production:
- Obtention d'une poignée avec le modèle d'accès "sûr".
- Fermer correctement les poignées natives
- Niveaux de confiance de la sécurité d'accès au code (CAS) (dans .NET Framework uniquement)
- Passer
SecureString
quand vous pouvez en récupérer un en toute sécurité via les frappes de l'utilisateur.
La quantité de code à écrire pour illustrer tout cela est au-delà de ce qui devrait être dans une réponse StackOverflow, à mon humble avis.
Une approche combinée et plus simple
Au lieu d'écrire tout cela vous-même, pensez à utiliser ma bibliothèque SimpleImpersonation , qui combine l'emprunt d'identité et l'accès utilisateur dans une seule API. Cela fonctionne bien dans les bases de code modernes et plus anciennes, avec la même API simple:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
});
ou
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
return something;
});
Notez qu'il est très similaire à l' WindowsIdentity.RunImpersonated
API, mais ne nécessite pas que vous sachiez quoi que ce soit sur les descripteurs de jetons.
Il s'agit de l'API à partir de la version 3.0.0. Consultez le fichier Lisez-moi du projet pour plus de détails. Notez également qu'une version précédente de la bibliothèque utilisait une API avec le IDisposable
modèle, similaire à WindowsIdentity.Impersonate
. La nouvelle version est beaucoup plus sûre et les deux sont toujours utilisées en interne.