2

简短版本是否可以在 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")返回假。

我正在测试在我的本地 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 中使用模拟来访问映射驱动器?

4

3 回答 3

1

不,但您可以使用符号链接。Mklink /d将创建一个目录链接。

于 2010-04-19T18:07:01.597 回答
0

您只能访问由被模拟用户创建的映射驱动器。

因此,如果您要模拟用户 X,然后映射共享(例如,通过网络使用),那么只要模拟有效,该共享就会可见。

您可以通过 确定当前可以访问哪些映射驱动器DriveInfo.GetDrives()。DriveType 为 Network 的驱动器可在当前安全上下文中访问。

于 2010-06-14T21:41:22.103 回答
0

我尝试了mklinkScott 的解决方案,但它不适用于 ASP.NET。

至于arnshea的回答:它根本不起作用;我什至冒充了域管理员,并将所有权限设置为每个人、iuser 和网络服务。

所以唯一的解决方案:当你设计你的 web 应用程序时,你必须决定是否要保存到网络资源并为此使用 UNC 协议。

映射的网络驱动器不适用于 ASP.NET 进行常规文件操作。

于 2011-10-05T07:01:35.043 回答