27 votes

Définir l'identité du fil

En C#, comment définir l'identité d'un thread ?

Par exemple, si j'ai le fil MyThread, qui est déjà lancé, puis-je changer l'identité de MyThread ?

Ou cela n'est-il pas possible ?

33voto

Martin Brown Points 8593

Vous pouvez définir l'identité d'un fil de discussion en créant un nouveau Principal. Vous pouvez utiliser n'importe quelle identité qui hérite de System.Security.Principal.IIdentity mais vous avez besoin d'une classe qui hérite de System.Security.Principal.IPrincipal qui prend en charge le type d'Identité que vous utilisez.
Par souci de simplicité, le cadre .Net fournit Principe générique y Identité générique qui peuvent être utilisées comme suit :

 using System.Security.Principal;

 // ...
 GenericIdentity identity = new GenericIdentity("M.Brown");
 identity.IsAuthenticated = true;

 // ...
 System.Threading.Thread.CurrentPrincipal =
    new GenericPrincipal(
        identity,
        new string[] { "Role1", "Role2" }
    );

 //...
 if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Role1"))
 {
      Console.WriteLine("Permission denied");
      return;
 }

Cela ne vous donnera cependant pas les droits Windows sur les choses utilisant la nouvelle identité. Mais cela peut être utile si vous développez un site web et que vous souhaitez créer votre propre gestion des utilisateurs.

Si vous souhaitez vous faire passer pour un utilisateur Windows différent du compte que vous utilisez actuellement, vous devez utiliser l'usurpation d'identité. Vous trouverez un exemple de cette méthode dans l'aide de l'application System.Security.Principal.WindowsIdentity.Impersonate() . Il existe des limitations quant aux comptes que le compte sous lequel vous travaillez peut usurper.

Dans certains cas, le cadre .Net se charge de l'usurpation d'identité à votre place. C'est le cas, par exemple, lorsque vous développez un site web ASP.Net et que l'authentification intégrée de Windows est activée pour le répertoire virtuel ou le site dans lequel vous travaillez.

4voto

Hakam Fostok Points 4765

Mise à jour pour la réponse acceptée [s'applique UNIQUEMENT sur .NET framework 4.5 et plus]
En .NET 4.5 la propriété IsAuthenticated n'a pas d'accesseur set, vous ne pouvez donc pas le définir directement comme le fait la réponse acceptée.
Vous pouvez utiliser le code suivant pour définir cette propriété.

GenericIdentity identity = new GenericIdentity("someuser", "Forms");
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });

3voto

dove Points 12456

Oui, en utilisant usurpation d'identité littéralement

using (new Impersonation())
{
    // your elevated code
}

et la classe est la suivante, pour les paramètres, j'utilise l'adaptateur de dictionnaire de château s'il semble étrange.

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
    private readonly SafeTokenHandle _handle;
    private readonly WindowsImpersonationContext _context;

    //const int Logon32LogonNewCredentials = 9; 
    private const int Logon32LogonInteractive = 2;

    public Impersonation()
    {
        var settings = Settings.Instance.Whatever;
        var domain = settings.Domain;
        var username = settings.User;
        var password = settings.Password;
        var ok = LogonUser(username, domain, password, Logon32LogonInteractive, 0, out _handle);
        if (!ok)
        {
            var errorCode = Marshal.GetLastWin32Error();
            throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code {0}.", errorCode));
        }
        _context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
    }

    public void Dispose()
    {
        _context.Dispose();
        _handle.Dispose();
    }

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
    private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true)
        { }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X