"Suplantación" en el espacio .NET generalmente significa ejecutar código bajo una cuenta de usuario específica. Es un concepto algo diferente que obtener acceso a esa cuenta de usuario a través de un nombre de usuario y contraseña, aunque estas dos ideas se combinan con frecuencia. Los describiré a ambos y luego explicaré cómo usar mi SimpleImpersonation biblioteca , que los usa internamente.
Interpretación
Las API para la suplantación se proporcionan en .NET a través del System.Security.Principal
espacio de nombres:
En general WindowsIdentity.RunImpersonated
, se debe usar un código más nuevo (.NET 4.6+, .NET Core, etc.) , que acepta un identificador para el token de la cuenta de usuario, y luego un código Action
o Func<T>
para que se ejecute el código.
WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
});
o
var result = WindowsIdentity.RunImpersonated(tokenHandle, () =>
{
// do whatever you want as this user.
return result;
});
El código anterior usaba el WindowsIdentity.Impersonate
método para recuperar un WindowsImpersonationContext
objeto. Este objeto se implementa IDisposable
, por lo que generalmente debe llamarse desde un using
bloque.
using (WindowsImpersonationContext context = WindowsIdentity.Impersonate(tokenHandle))
{
// do whatever you want as this user.
}
Si bien esta API todavía existe en .NET Framework, generalmente debe evitarse y no está disponible en .NET Core o .NET Standard.
Accediendo a la cuenta de usuario
La API para usar un nombre de usuario y contraseña para obtener acceso a una cuenta de usuario en Windows es LogonUser
, que es una API nativa de Win32. Actualmente no hay una API .NET incorporada para llamarlo, por lo que se debe recurrir a P / Invoke.
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
Esta es la definición básica de la llamada, sin embargo, hay mucho más que considerar para usarla realmente en producción:
- Obtención de un identificador con el patrón de acceso "seguro".
- Cerrar los manejadores nativos apropiadamente
- Niveles de confianza de seguridad de acceso al código (CAS) (solo en .NET Framework)
- Pasando
SecureString
cuando puede recoger uno de forma segura a través de las pulsaciones de teclas del usuario.
La cantidad de código para escribir para ilustrar todo esto está más allá de lo que debería estar en una respuesta de StackOverflow, en mi humilde opinión.
Un enfoque combinado y más fácil
En lugar de escribir todo esto usted mismo, considere usar mi biblioteca SimpleImpersonation , que combina la suplantación y el acceso del usuario en una sola API. Funciona bien en bases de código modernas y antiguas, con la misma API simple:
var credentials = new UserCredentials(domain, username, password);
Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
});
o
var credentials = new UserCredentials(domain, username, password);
var result = Impersonation.RunAsUser(credentials, logonType, () =>
{
// do whatever you want as this user.
return something;
});
Tenga en cuenta que es muy similar a la WindowsIdentity.RunImpersonated
API, pero no requiere que sepa nada sobre los identificadores de token.
Esta es la API a partir de la versión 3.0.0. Vea el archivo Léame del proyecto para más detalles. También tenga en cuenta que una versión anterior de la biblioteca utilizaba una API con el IDisposable
patrón, similar a WindowsIdentity.Impersonate
. La versión más nueva es mucho más segura, y ambas aún se usan internamente.