[.NET] Impersonation : changer d’utilisateur (WindowsIdentity) à la volée

Le 6 août 2010 à 15:51

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) :

image


Donc bien entendu, si avec mon compte par défaut, je souhaite y accéder :


image

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 :

image

Pour télécharger les sources, c’est ici.

A bientôt !

Ajouter un commentaire

biuquote
  • Commentaire
  • Prévisualiser
Loading

A propos de l'auteur

Mathieu Perrein - Software Solutions Manager, Software Architect, Trainer MCT, MSP de 2010 à 2012.

 

MSP

 

MSP

MSP

 MSPD

MCT

 

Facebook

 

Ce blog est strictement personnel et les opinions exprimées ici n'engagent donc que moi, et pas mon employeur.

Tags

Vous avez désactivé JavaScript ou bien vous possédez une ancienne version d'Adobe Flash Player. Téléchargez la dernière version de Flash Player.