短版:是否可以在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。
我正在使用在我的本地Windows 7 Professional机器上运行的IIS 7进行测试,但这需要在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中使用模拟来访问映射的驱动器?
答案 0 :(得分:1)
不,但您可以使用符号链接。 Mklink /d
将创建目录链接。
答案 1 :(得分:0)
您只能访问由模拟用户创建的映射驱动器。
因此,如果您冒充用户X然后映射共享(例如,通过网络使用),那么只要模拟生效,该共享就会可见。
您可以通过DriveInfo.GetDrives()
确定当前可以访问的映射驱动器。具有DriveType of Network的驱动器可在当前安全上下文中访问。
答案 2 :(得分:0)
我尝试了mklink
solution from Scott,但它无法使用ASP.NET。
至于arnshea的回答:它根本不起作用;我甚至模仿域管理员,并将所有权限设置为所有人,iuser和网络服务。
所以唯一的解决方案是:在设计Web应用程序时,您必须决定是否要保存到网络资源并使用UNC协议。
映射的网络驱动器不能与ASP.NET一起用于常规文件操作。