Pour les besoins d’un projet, j’ai besoin d’utiliser temporairement un compte avec d’autres privilèges (par exemple, même si c’est faisable autrement, si vous avez besoin d’accéder à des ressources réseaux ou tout simplement, comme il sera montré dans l’exemple, d’accéder à un répertoire où l’utilisateur courant n’a pas les droits). Pour simplifier l’utilisation, j’ai crée une (simple) classe qui sera présentée ici.
Tout d’abord, voici la classe Impersonation, qui permet de changer d’utilisateur :
public class Impersonation : IDisposable
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool
LogonUser(string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);
private const int LOGON32_PROVIDER_DEFAULT = 0;
private const int LOGON32_LOGON_INTERACTIVE = 2;
private WindowsImpersonationContext _impersonationContext;
public Impersonation(string domain, string login, string password)
{
try
{
IntPtr tokenHdle = IntPtr.Zero;
bool ret = LogonUser(login, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, out tokenHdle);
Trace.WriteLine("Current user : " + WindowsIdentity.GetCurrent().Name);
WindowsIdentity newIdentity = new WindowsIdentity(tokenHdle);
_impersonationContext = newIdentity.Impersonate();
Trace.WriteLine("Current user : " + WindowsIdentity.GetCurrent().Name);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
#region IDisposable Membres
public void Dispose()
{
_impersonationContext.Undo();
Trace.WriteLine("Current user : " + WindowsIdentity.GetCurrent().Name);
}
#endregion
}
Dans l’exemple qui va suivre, j’ai crée un dossier Test où j’ai enlever tous les droits pour ne laisser qu’un compte temporaire (juste pour mon exemple) :
Donc bien entendu, si avec mon compte par défaut, je souhaite y accéder :
Maintenant nous allons essayer de créer un fichier dans ce dossier avec l’utilisateur où je n’ai pas les droits, puis tout de suite derrière on va utiliser la classe Impersonation pour pouvoir basculer vers l’utilisateur “MathieuTest” afin d’avoir l’autorisation de créer le fichier :
static void Main(string[] args)
{
string userName, password;
Console.WriteLine("Impersonation Sample");
Console.WriteLine("--------------------");
Console.WriteLine(@"Pour cet exemple,
nous allons essayer de créer le fichier
E:\Test\File.txt dont le dossier n'est accessible
que pour un utilisateur");
Console.Write("Essai n°1 : ");
Console.WriteLine(Test());
Console.WriteLine("Donc on va utiliser l'impersonation pour pouvoir
utiliser temporairement \"son compte\" afin de pouvoir
créer le fichier");
Console.Write("Username : ");
userName = Console.ReadLine();
Console.Write("Password : ");
password = Console.ReadLine();
Console.Write("Essai n°2 : ");
// On tente avec l'impersonation
Impersonation impersonation = new Impersonation(string.Empty, userName, password);
Console.WriteLine(Test());
// On revient à l'utilisateur "en cours"
impersonation.Dispose();
Console.Read();
}
static string Test()
{
try
{
File.Create(@"E:\Test\File.txt");
return "Fichier crée";
}
catch (Exception e)
{
return @"/!\ Impossible de créer le fichier";
}
}
Voici le résultat dans la console :
Pour télécharger les sources, c’est ici.
A bientôt !