Définir L'identité du Thread
En C#, comment définir l'identité d'un Thread?
Par exemple, si J'ai thread MyThread, qui est déjà démarré, puis-je changer L'identité de MyThread?
Ou n'est-ce pas possible?
3 réponses
Vous pouvez définir L'identité d'un thread en créant un nouveau Principal. Vous pouvez utiliser N'importe quelle identité héritée du système .Sécurité.Principal.IIdentity , mais vous avez besoin d'une classe qui hérite du système .Sécurité.Principal.IPrincipal {[3] } qui prend le type D'identité que vous utilisez.
par souci de simplicité, le framework. NET fournit GenericPrincipal et GenericIdentity classes qui peuvent être utilisées comme ceci:
using System.Security.Principal;
// ...
GenericIdentity identity = new GenericIdentity("M.Brown");
identity.IsAuthenticated = true;
// ...
System.Threading.Thread.CurrentPrincipal =
new GenericPrincipal(
identity,
new string[] { "Role1", "Roll2" }
);
//...
if (!System.Threading.Thread.CurrentPrincipal.IsInRole("Roll1"))
{
Console.WriteLine("Permission denied");
return;
}
Cela ne vous donnera cependant pas Droits windows pour les choses en utilisant la nouvelle identité. Mais il peut être utile si vous développez un site web et souhaitez créer votre propre gestion des utilisateurs.
Si vous voulez faire semblant D'être un utilisateur Windows différent du compte que vous utilisez actuellement, vous devez utiliser l'usurpation d'identité. Un exemple de ceci peut être trouvé dans l'Aide de Système.Sécurité.Principal.WindowsIdentity.Imiter () . Il y a des limites sur les comptes sous lesquels le compte que vous exécutez peut usurper.
Dans certains cas, le framework. Net fait une usurpation d'identité pour vous. Un exemple de l'endroit où cela se produit est si vous développez un ASP.Net site web et vous avez intégré L'authentification Windows activée pour le répertoire virtuel ou le site dans lequel vous exécutez.
Oui, en utilisant l'usurpation d'identité littéralement
using (new Impersonation())
{
// your elevated code
}
Et la classe est la suivante, pour les paramètres, j'utilise castle dictionary adaptor si cela 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);
}
}
}
Ceci est une mise à jour pour la réponse acceptée [appliquer sur. NET framework 4.5 et supérieur]
Dans .NET 4.5
la propriété IsAuthenticated
n'a pas d'accesseur défini, donc vous ne pouvez pas le définir directement comme 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" });