c# - Establecer la identidad del hilo
.net multithreading (3)
Puede establecer la Identidad de un hilo creando un nuevo Principal. Puede usar cualquier identidad que herede de System.Security.Principal.IIdentity , pero necesita una clase que herede de System.Security.Principal.IPrincipal que tome el tipo de identidad que está utilizando.
Para simplificar, .Net Framework proporciona las clases GenericPrincipal y GenericIdentity que se pueden usar de esta manera:
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;
}
Sin embargo, esto no le otorgará derechos de Windows a las cosas con la nueva identidad. Pero puede ser útil si está desarrollando un sitio web y desea crear su propia administración de usuarios.
Si desea fingir ser un usuario de Windows diferente a la cuenta que está utilizando en ese momento, debe usar la suplantación. Se puede encontrar un ejemplo de cómo hacerlo en la Ayuda de System.Security.Principal.WindowsIdentity.Impersonate () . Existen limitaciones sobre las cuentas con las que se puede suplantar la cuenta bajo la que se está ejecutando.
En algunos casos, el framework .Net hace suplantación por usted. Un ejemplo de dónde ocurre esto es si está desarrollando un sitio web ASP.Net y tiene la Autenticación integrada de Windows activada para el directorio virtual o sitio en el que se está ejecutando.
En C #, ¿cómo configuro la identidad de un hilo?
Por ejemplo, si tengo Thread MyThread, que ya está iniciado, ¿puedo cambiar la identidad de MyThread?
O esto no es posible?
Sí, usando suplantación literalmente
using (new Impersonation())
{
// your elevated code
}
y la clase es la siguiente, para las configuraciones que uso castle dictionary adapter si se ve extraño.
[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);
}
}
}
Esta es una actualización de la respuesta aceptada [se aplica en .NET framework 4.5 y posteriores]
En .NET 4.5
la propiedad IsAuthenticated
no tiene ningún acceso de conjunto, por lo que no puede establecerlo directamente como la respuesta aceptada.
Puede usar el siguiente código para establecer esa propiedad.
GenericIdentity identity = new GenericIdentity("someuser", "Forms");
Thread.CurrentPrincipal = new GenericPrincipal(identity, new string[] { "somerole" });