Короткая версия : Можно или нет использовать олицетворение в 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 для доступа к подключенным дискам?