Acceso a unidades mapeadas cuando se hace pasar por ASP.NET
Version corta: ¿Es posible o no utilizar la suplantación en ASP.NET para acceder a unidades mapeadas?
Versión larga:
Actualmente estoy usando la suplantación en ASP.NET para obtener acceso a los archivos de red. Esto funciona perfectamente para cualquier archivo de red que use una ruta UNC, pero no puede acceder a ningún archivo en unidades mapeadas definidas para la cuenta de usuario que estoy suplantando.
Por ejemplo, supongamos que un archivo vive en la red en\\machine\folder\file.txt
, y también digamos que conducirS:
se asigna a\\machine\folder
. Necesitamos poder acceder a la ruta completa de UNC,\\machine\folder\file.txt
, así como la ruta de acceso más corta y asignada,S:\file.txt
.
Obviamente, el proceso estándar ASP.NET tampoco puede acceder.
Usando una aplicación de consola que se ejecuta bajo la cuenta local con el mapeadoS:
conducir, llamandoFile.Exists(@"\\machine\folder\file.txt")
devuelve verdadero yFile.Exists(@"S:\file.txt")
También devuelve verdadero.
Sin embargo, cuando se hace pasar por un contexto ASP.NET con la misma cuenta local, soloFile.Exists(@"\\machine\folder\file.txt")
devuelve verdaderoFile.Exists(@"S:\file.txt")
devuelve falso
Estoy probando con IIS 7 ejecutándose en mi cuadro local de Windows 7 Professional, aunque esto tendrá que ejecutarse tanto en IIS 6 como en IIS 7.
La suplantación se maneja con un par de clases en C # que incluiré aquí:
public static class Impersonation
{
private static WindowsImpersonationContext context;
public static void ImpersonateUser(string username, string password)
{
ImpersonateUser(".", username, password);
}
public static void ImpersonateUser(string domain, string username, string password)
{
StopImpersonating();
IntPtr userToken;
var returnValue = ImpersonationImports.LogonUser(username, domain, password,
ImpersonationImports.LOGON32_LOGON_INTERACTIVE,
ImpersonationImports.LOGON32_PROVIDER_DEFAULT,
out userToken);
context = WindowsIdentity.Impersonate(userToken);
}
public static void StopImpersonating()
{
if (context != null)
{
context.Undo();
context = null;
}
}
}
public static class ImpersonationImports
{
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_LOGON_NETWORK = 3;
public const int LOGON32_LOGON_BATCH = 4;
public const int LOGON32_LOGON_SERVICE = 5;
public const int LOGON32_LOGON_UNLOCK = 7;
public const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
public const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
public const int LOGON32_PROVIDER_DEFAULT = 0;
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int LogonUser(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken
);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int ImpersonateLoggedOnUser(
IntPtr hToken
);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RevertToSelf();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr hObject);
}
Luego, durante Page_Load, básicamente hacemos algo como esto:
Impersonation.ImpersonateUser("DOMAIN", "username", "password");
if (!File.Exists(@"S:\file.txt"))
throw new WeCannotContinueException();
Me doy cuenta de que usar unidades mapeadas no es una práctica recomendada, pero por razones heredadas es deseable para nuestro negocio.¿Es posible o no utilizar la suplantación en ASP.NET para acceder a unidades mapeadas?