在 ASP.NET 中模拟时访问映射驱动器
简短版本:是否可以在 ASP.NET 中使用模拟来访问映射驱动器?
长版本:
我目前正在使用模拟在 ASP.NET 中获取对网络文件的访问权限。这对于使用 UNC 路径的任何网络文件都适用,但无法访问为我模拟的用户帐户定义的映射驱动器上的任何文件。
例如,假设文件位于网络上的 \\machine\folder\file.txt
,并且还假设驱动器 S:
映射到 \\机器\文件夹
。我们需要能够访问完整的 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 中使用模拟来访问映射驱动器?
Short version: Is it possible or not to use impersonation in ASP.NET to access mapped drives?
Long Version:
I'm currently using impersonation in ASP.NET to gain access to network files. This is working perfectly for any network file using a UNC path, but it is failing to access any files on mapped drives defined for the user account I'm impersonating.
For example, let's say a file lives on the network at \\machine\folder\file.txt
, and let's also say that drive S:
is mapped to \\machine\folder
. We need to be able to access both the full UNC path, \\machine\folder\file.txt
, as well as the shorter, mapped drive path, S:\file.txt
.
Obviously the standard ASP.NET process cannot access either.
Using a console application that runs under the local account with the mapped S:
drive, calling File.Exists(@"\\machine\folder\file.txt")
returns true, and File.Exists(@"S:\file.txt")
also returns true.
However, when impersonating in an ASP.NET context with the same local account, only File.Exists(@"\\machine\folder\file.txt")
returns true. File.Exists(@"S:\file.txt")
returns false.
I'm testing with IIS 7 running on my local Windows 7 Professional box, though this will need to run in both IIS 6 and IIS 7.
Impersonation is handled with a couple of classes in C# which I'll include here:
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);
}
Then, during Page_Load, we basically do something like this:
Impersonation.ImpersonateUser("DOMAIN", "username", "password");
if (!File.Exists(@"S:\file.txt"))
throw new WeCannotContinueException();
I realize using mapped drives isn't a best practice, but for legacy reasons it's desirable for our business. Is it possible or not to use impersonation in ASP.NET to access mapped drives?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不,但您可以使用符号链接。
Mklink /d
将创建一个目录链接。No, but you can use a symbolic link instead.
Mklink /d
will create a directory link.您只能访问由被模拟的用户创建的映射驱动器。
因此,如果您要模拟用户 X 然后映射共享(例如,通过网络使用),那么只要模拟有效,该共享就将可见。
您可以通过
DriveInfo.GetDrives()
确定当前可以访问哪些映射驱动器。 DriveType 为 Network 的驱动器可在当前安全上下文中访问。You can only access mapped drives that were created by the user being impersonated.
So if you were to impersonate user X then map the share (e.g., via net use) then that share will be visible for as long as the impersonation is in effect.
You can determine which mapped drives are currently accessible via
DriveInfo.GetDrives()
. Drives with a DriveType of Network are accessible in the current security context.我尝试了
mklink
解决方案来自 Scott,它不适用于 ASP.NET。至于 arnshea 的回答:它根本不起作用;我什至冒充了域管理员,并将所有权限设置为每个人、iuser 和网络服务。
因此,唯一的解决方案是:当您设计 Web 应用程序时,您必须决定是否要保存到网络资源并使用 UNC 协议。
映射的网络驱动器不能与 ASP.NET 一起用于常规文件操作。
I tried the
mklink
solution from Scott, and it is not working with ASP.NET.As for answer from arnshea: it is not working at all; I even impersonated with the domain administrator, and all permissions set to everyone, iuser and network service.
So the only solution: when you design your web application you must decide whether you want to save to network resource and use the UNC protocol for that.
A mapped network drive does not work with ASP.NET for regular file operations.