短いバージョン:マップされたドライブにアクセスするためにASP.NETで偽装を使用することは可能ですか?
ロングバージョン:
現在、ASP.NETで偽装を使用して、ネットワークファイルにアクセスしています。これは、UNCパスを使用するすべてのネットワークファイルで完全に機能しますが、偽装しているユーザーアカウント用に定義されたマップされたドライブ上のファイルにアクセスできません。
たとえば、ファイルがのネットワーク上に存在し\\machine\folder\file.txt
、ドライブS:
がにマップされているとし\\machine\folder
ます。\\machine\folder\file.txt
フルUNCパスと、より短いマップされたドライブパスの両方にアクセスできる必要がありますS:\file.txt
。
明らかに、標準のASP.NETプロセスもアクセスできません。
マップされたS:
ドライブを使用してローカルアカウントで実行されるコンソールアプリケーションを使用すると、呼び出しFile.Exists(@"\\machine\folder\file.txt")
はtrueを返し、trueFile.Exists(@"S:\file.txt")
も返します。
ただし、同じローカルアカウントを使用してASP.NETコンテキストで偽装する場合は、 File.Exists(@"\\machine\folder\file.txt")
trueのみを返します。File.Exists(@"S:\file.txt")
falseを返します。
ローカルのWindows7ProfessionalボックスでIIS7を実行してテストしていますが、これはIIS6とIIS7の両方で実行する必要があります。
なりすましは、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で偽装を使用することは可能ですか?