Краткая версия: Можно или нет использовать олицетворение в ASP.NET для доступа к подключенным дискам?
Полная версия:
В настоящее время я использую олицетворение в ASP.NET для доступа к сетевым файлам. Это отлично работает для любого сетевого файла, использующего UNC-путь, но не может получить доступ к каким-либо файлам на подключенных дисках, определенных для учетной записи пользователя, которую я выдаю за себя.
Например, предположим, что файл находится в сети по адресу \\machine\folder\file.txt
, и предположим, что диск S:
сопоставлен с \\machine\folder
. Нам необходимо иметь доступ как к полному пути UNC, \\machine\folder\file.txt
, так и к более короткому пути сопоставленного диска, S:\file.txt
.
Очевидно, что стандартный процесс ASP.NET тоже не имеет доступа.
При использовании консольного приложения, которое запускается под локальной учетной записью с подключенным S:
диском, вызов File.Exists(@"\\machine\folder\file.txt")
возвращает true, а File.Exists(@"S:\file.txt")
также возвращает true.
Однако при олицетворении в контексте ASP.NET с той же локальной учетной записью только File.Exists(@"\\machine\folder\file.txt")
возвращает значение true. File.Exists(@"S:\file.txt")
возвращает false.
Я тестирую IIS 7, работающий на моем локальном компьютере с Windows 7 Professional, хотя он должен работать как в IIS 6, так и в IIS 7.
Олицетворение обрабатывается парой классов в C #, которые я включу сюда:
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);
}
Затем во время Page_Load мы делаем что-то вроде этого:
Impersonation.ImpersonateUser("DOMAIN", "username", "password");
if (!File.Exists(@"S:\file.txt"))
throw new WeCannotContinueException();
Я понимаю, что использование подключенных дисков - не лучшая практика, но по устаревшим причинам это желательно для нашего бизнеса. Можно ли использовать олицетворение в ASP.NET для доступа к подключенным дискам?