dowsImpersonationContext访问网络驱动器模

dowsImpersonationContext访问网络驱动器模

本文介绍了使用WindowsImpersonationContext访问网络驱动器模拟当前用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从一个Web应用程序访问远程驱动器。该驱动器无法访问ASP.NET进程,所以我想模拟当前用户的请求。

我看到使用WindowsImpersonationContext一些基本的例子,并尝试以下。

  WindowsImpersonationContext impersonationContext = NULL;

尝试
{
    impersonationContext =((的WindowsIdentity)User.Identity).Impersonate();

    file.SaveAs(文件路径);
}
最后
{
    如果(impersonationContext!= NULL)
    {
        impersonationContext.Undo();
    }
}
 

我仍然得到拒绝访问异常。

我读了一点东西约的LogonUser ,但据我可以告诉你需要一个用户名和密码,以获得该证书。我不是在寻找一个不同的特定用户,只需将当前用户(谁应该有权限访问的文件存储)登录,所以我不认为我真正需要的的LogonUser API

没有人有任何想法,我缺少的是什么?如若上述code的工作?

我也想指出,包括

<身份冒充=真/>

不工作,但包括

<身份冒充=真的userName =MYNAME密码=MYPASSWORD/>

的web.config 让我进去。我见过几个人问这是为什么的问题,但我看到没有解释。我想知道,如果它连接到我的问题虽然。

解决方案

我写的确实是一个辅助类:

 公共静态类ImpersonationUtils
{
    私人const int的SW_SHOW = 5;
    私人const int的TOKEN_QUERY =×0008;
    私人const int的TOKEN_DUPLICATE = 0×0002;
    私人const int的TOKEN_ASSIGN_PRIMARY = 0×0001;
    私人const int的STARTF_USESHOWWINDOW = 00000001;
    私人const int的STARTF_FORCEONFEEDBACK = 0x00000040;
    私人const int的CREATE_UNI code_ENVIRONMENT = 0x00000400时;
    私人const int的TOKEN_IMPERSONATE =×0004;
    私人const int的TOKEN_QUERY_SOURCE = 0×0010;
    私人const int的TOKEN_ADJUST_PRIVILEGES = 0×0020;
    私人const int的TOKEN_ADJUST_GROUPS = 0x0040;
    私人const int的TOKEN_ADJUST_DEFAULT = 0x0080;
    私人const int的TOKEN_ADJUST_SESSIONID = 0100;
    私人const int的STANDARD_RIGHTS_REQUIRED = 0x000F0000;
    私人const int的TOKEN_ALL_ACCESS =
        STANDARD_RIGHTS_REQUIRED |
        TOKEN_ASSIGN_PRIMARY |
        TOKEN_DUPLICATE |
        TOKEN_IMPERSONATE |
        TOKEN_QUERY |
        TOKEN_QUERY_SOURCE |
        TOKEN_ADJUST_PRIVILEGES |
        TOKEN_ADJUST_GROUPS |
        TOKEN_ADJUST_DEFAULT |
        TOKEN_ADJUST_SESSIONID;

    [StructLayout(LayoutKind.Sequential)
    私人结构PROCESS_INFORMATION
    {
        公共IntPtr的hProcess;
        公众的IntPtr hThread;
        公众诠释dwProcessId;
        公众诠释dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)
    私人结构SECURITY_ATTRIBUTES
    {
        公众诠释nLength;
        公众的IntPtr lpSecurityDescriptor;
        公共BOOL bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)
    私人结构STARTUPINFO
    {
        公众诠释CB;
        公共字符串升preserved;
        公共字符串lpDesktop;
        公共字符串lpTitle;
        公众诠释DWX;
        公众诠释DWY;
        公众诠释dwXSize;
        公众诠释dwYSize;
        公众诠释dwXCountChars;
        公众诠释dwYCountChars;
        公众诠释dwFillAttribute;
        公众诠释dwFlags中;
        公共短wShowWindow;
        公共短cbReserved2;
        公众的IntPtr升preserved2;
        公众的IntPtr hStdInput;
        公众的IntPtr hStdOutput;
        公众的IntPtr hStdError;
    }

    私人枚举SECURITY_IMPERSONATION_LEVEL
    {
        SecurityAnonymous,
        SecurityIdentification,
        SecurityImpersonation,
        SecurityDelegation
    }

    私人枚举TOKEN_TYPE
    {
        TokenPrimary = 1,
        TokenImpersonation
    }

    [的DllImport(advapi32.dll的,SetLastError =真)
    私人静态外部布尔CreateProcessAsUser(
        IntPtr的hToken,
        串lpApplicationName,
        串lpCommandLine,
        裁判SECURITY_ATTRIBUTES lpProcessAttributes,
        裁判SECURITY_ATTRIBUTES lpThreadAttributes,
        布尔bInheritHandles,
        INT dwCreationFlags,
        IntPtr的lpEnvironment,
        串lpCurrentDirectory,
        裁判STARTUPINFO lpStartupInfo,
        出PROCESS_INFORMATION lpProcessInformation);

    [的DllImport(advapi32.dll的,SetLastError =真)
    私人静态外部布尔DuplicateTokenEx(
        IntPtr的hExistingToken,
        INT dwDesiredAccess,
        裁判SECURITY_ATTRIBUTES lpThreadAttributes,
        INT ImpersonationLevel,
        INT dwTokenType,
        裁判的IntPtr phNewToken);

    [的DllImport(advapi32.dll的,SetLastError =真)
    私人静态外部布尔OpenProcessToken(
        IntPtr的ProcessHandle,
        INT DesiredAccess,
        裁判的IntPtr TokenHandle);

    [的DllImport(userenv.dll,SetLastError =真)
    私人静态外部布尔CreateEnvironmentBlock(
            裁判的IntPtr lpEnvironment,
            IntPtr的hToken,
            布尔bInherit);

    [的DllImport(userenv.dll,SetLastError =真)
    私人静态外部布尔DestroyEnvironmentBlock(
            IntPtr的lpEnvironment);

    [的DllImport(KERNEL32.DLL,SetLastError =真)
    私有静态的extern BOOL CloseHandle的(
        IntPtr的hObject);

    私有静态无效LaunchProcessAsUser(字符串CMDLINE,IntPtr的道理,IntPtr的envBlock,诠释的sessionId)
    {
        VAR PI =新PROCESS_INFORMATION();
        VAR saProcess =新SECURITY_ATTRIBUTES();
        VAR saThread =新SECURITY_ATTRIBUTES();
        saProcess.nLength = Marshal.SizeOf(saProcess);
        saThread.nLength = Marshal.SizeOf(saThread);

        变种SI =新STA​​RTUPINFO();
        si.cb = Marshal.SizeOf(SI);
        si.lpDesktop = @WinSta0 \默认;
        si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
        si.wShowWindow = SW_SHOW;

        如果(!CreateProcessAsUser(
            令牌,
            空值,
            CMDLINE,
            REF saProcess,
            REF saThread,
            假,
            CREATE_UNI code_ENVIRONMENT,
            envBlock,
            空值,
            REF SI,
            出圆周率))
        {
            抛出新Win32Exception(Marshal.GetLastWin32Error(),CreateProcessAsUser失败);
        }
    }

    私有静态IDisposable的模仿(IntPtr的令牌)
    {
        VAR身份=新的WindowsIdentity(标记);
        返回identity.Impersonate();
    }

    私有静态的IntPtr GetPrimaryToken(工艺过程)
    {
        VAR令牌= IntPtr.Zero;
        VAR primaryToken = IntPtr.Zero;

        如果(OpenProcessToken(process.Handle,TOKEN_DUPLICATE,裁判令牌))
        {
            VAR SA =新SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(SA);

            如果(!DuplicateTokenEx(
                令牌,
                TOKEN_ALL_ACCESS,
                REF SA,
                (INT)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                (INT)TOKEN_TYPE.TokenPrimary,
                裁判primaryToken))
            {
                抛出新Win32Exception(Marshal.GetLastWin32Error(),DuplicateTokenEx失败);
            }

            CloseHandle的(标记);
        }
        其他
        {
            抛出新Win32Exception(Marshal.GetLastWin32Error(),OpenProcessToken失败);
        }

        返回primaryToken;
    }

    私有静态的IntPtr GetEnvironmentBlock(IntPtr的令牌)
    {
        VAR envBlock = IntPtr.Zero;
        如果(!CreateEnvironmentBlock(REF envBlock,令牌,FALSE))
        {
            抛出新Win32Exception(Marshal.GetLastWin32Error(),CreateEnvironmentBlock失败);
        }
        返回envBlock;
    }

    公共静态无效LaunchAsCurrentUser(字符串CMDLINE)
    {
        VAR方法= Process.GetProcessesByName(资源管理器)FirstOrDefault()。
        如果(处理!= NULL)
        {
            VAR令牌= GetPrimaryToken(过程);
            如果(令牌!= IntPtr.Zero)
            {
                VAR envBlock = GetEnvironmentBlock(标记);
                如果(envBlock!= IntPtr.Zero)
                {
                    LaunchProcessAsUser(CMDLINE,令牌,envBlock,process.SessionId);
                    如果(!DestroyEnvironmentBlock(envBlock))
                    {
                        抛出新Win32Exception(Marshal.GetLastWin32Error(),DestroyEnvironmentBlock失败);
                    }
                }

                CloseHandle的(标记);
            }
        }
    }

    公共静态IDisposable的ImpersonateCurrentUser()
    {
        VAR方法= Process.GetProcessesByName(资源管理器)FirstOrDefault()。
        如果(处理!= NULL)
        {
            VAR令牌= GetPrimaryToken(过程);
            如果(令牌!= IntPtr.Zero)
            {
                返回冒充(标记);
            }
        }

        抛出新的异常(无法找到Explorer.exe的);
    }
}
 

您可以使用它这样的:

  ImpersonationUtils.LaunchAsCurrentUser(记事本);

使用(ImpersonationUtils.ImpersonateCurrentUser())
{

}
 

更多解释和例子,你可以在这里找到:

冒充来自系统的currentUser

I need to access a remote drive from a Web App. The drive isn't accessible to the ASP.NET process, so I want to impersonate the current user for the request.

I saw some basic examples using WindowsImpersonationContext, and have tried the following.

WindowsImpersonationContext impersonationContext = null;

try
{
    impersonationContext = ((WindowsIdentity)User.Identity).Impersonate();

    file.SaveAs(filePath);
}
finally
{
    if (impersonationContext != null)
    {
        impersonationContext.Undo();
    }
}

I'm still getting an access denied exception.

I've read a bit of stuff about LogonUser, but as far as I can tell you need a user name and password to get credentials from that. I'm not looking to log in as a different specific user, just the current user (who should have permissions to access the file store), so I don't think I actually need the LogonUser API.

Does anyone have any idea what I'm missing? Should the above code work?

I'd also note that including

<identity impersonate="true" />

doesn't work, but including

<identity impersonate="true" userName="myName" password="myPassword" />

in the web.config lets me in. I've seen a few people ask questions about why this is, but I've seen no explanation. I'm wondering if it is connected to my problem though.

解决方案

I wrote a helper class that does it:

public static class ImpersonationUtils
{
    private const int SW_SHOW = 5;
    private const int TOKEN_QUERY = 0x0008;
    private const int TOKEN_DUPLICATE = 0x0002;
    private const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    private const int STARTF_USESHOWWINDOW = 0x00000001;
    private const int STARTF_FORCEONFEEDBACK = 0x00000040;
    private const int CREATE_UNICODE_ENVIRONMENT = 0x00000400;
    private const int TOKEN_IMPERSONATE = 0x0004;
    private const int TOKEN_QUERY_SOURCE = 0x0010;
    private const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    private const int TOKEN_ADJUST_GROUPS = 0x0040;
    private const int TOKEN_ADJUST_DEFAULT = 0x0080;
    private const int TOKEN_ADJUST_SESSIONID = 0x0100;
    private const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
    private const int TOKEN_ALL_ACCESS =
        STANDARD_RIGHTS_REQUIRED |
        TOKEN_ASSIGN_PRIMARY |
        TOKEN_DUPLICATE |
        TOKEN_IMPERSONATE |
        TOKEN_QUERY |
        TOKEN_QUERY_SOURCE |
        TOKEN_ADJUST_PRIVILEGES |
        TOKEN_ADJUST_GROUPS |
        TOKEN_ADJUST_DEFAULT |
        TOKEN_ADJUST_SESSIONID;

    [StructLayout(LayoutKind.Sequential)]
    private struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        public bool bInheritHandle;
    }

    [StructLayout(LayoutKind.Sequential)]
    private struct STARTUPINFO
    {
        public int cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public int dwX;
        public int dwY;
        public int dwXSize;
        public int dwYSize;
        public int dwXCountChars;
        public int dwYCountChars;
        public int dwFillAttribute;
        public int dwFlags;
        public short wShowWindow;
        public short cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    private enum SECURITY_IMPERSONATION_LEVEL
    {
        SecurityAnonymous,
        SecurityIdentification,
        SecurityImpersonation,
        SecurityDelegation
    }

    private enum TOKEN_TYPE
    {
        TokenPrimary = 1,
        TokenImpersonation
    }

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool CreateProcessAsUser(
        IntPtr hToken,
        string lpApplicationName,
        string lpCommandLine,
        ref SECURITY_ATTRIBUTES lpProcessAttributes,
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        bool bInheritHandles,
        int dwCreationFlags,
        IntPtr lpEnvironment,
        string lpCurrentDirectory,
        ref STARTUPINFO lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool DuplicateTokenEx(
        IntPtr hExistingToken,
        int dwDesiredAccess,
        ref SECURITY_ATTRIBUTES lpThreadAttributes,
        int ImpersonationLevel,
        int dwTokenType,
        ref IntPtr phNewToken);

    [DllImport("advapi32.dll", SetLastError = true)]
    private static extern bool OpenProcessToken(
        IntPtr ProcessHandle,
        int DesiredAccess,
        ref IntPtr TokenHandle);

    [DllImport("userenv.dll", SetLastError = true)]
    private static extern bool CreateEnvironmentBlock(
            ref IntPtr lpEnvironment,
            IntPtr hToken,
            bool bInherit);

    [DllImport("userenv.dll", SetLastError = true)]
    private static extern bool DestroyEnvironmentBlock(
            IntPtr lpEnvironment);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(
        IntPtr hObject);

    private static void LaunchProcessAsUser(string cmdLine, IntPtr token, IntPtr envBlock, int sessionId)
    {
        var pi = new PROCESS_INFORMATION();
        var saProcess = new SECURITY_ATTRIBUTES();
        var saThread = new SECURITY_ATTRIBUTES();
        saProcess.nLength = Marshal.SizeOf(saProcess);
        saThread.nLength = Marshal.SizeOf(saThread);

        var si = new STARTUPINFO();
        si.cb = Marshal.SizeOf(si);
        si.lpDesktop = @"WinSta0\Default";
        si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
        si.wShowWindow = SW_SHOW;

        if (!CreateProcessAsUser(
            token,
            null,
            cmdLine,
            ref saProcess,
            ref saThread,
            false,
            CREATE_UNICODE_ENVIRONMENT,
            envBlock,
            null,
            ref si,
            out pi))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateProcessAsUser failed");
        }
    }

    private static IDisposable Impersonate(IntPtr token)
    {
        var identity = new WindowsIdentity(token);
        return identity.Impersonate();
    }

    private static IntPtr GetPrimaryToken(Process process)
    {
        var token = IntPtr.Zero;
        var primaryToken = IntPtr.Zero;

        if (OpenProcessToken(process.Handle, TOKEN_DUPLICATE, ref token))
        {
            var sa = new SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(sa);

            if (!DuplicateTokenEx(
                token,
                TOKEN_ALL_ACCESS,
                ref sa,
                (int)SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                (int)TOKEN_TYPE.TokenPrimary,
                ref primaryToken))
            {
                throw new Win32Exception(Marshal.GetLastWin32Error(), "DuplicateTokenEx failed");
            }

            CloseHandle(token);
        }
        else
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "OpenProcessToken failed");
        }

        return primaryToken;
    }

    private static IntPtr GetEnvironmentBlock(IntPtr token)
    {
        var envBlock = IntPtr.Zero;
        if (!CreateEnvironmentBlock(ref envBlock, token, false))
        {
            throw new Win32Exception(Marshal.GetLastWin32Error(), "CreateEnvironmentBlock failed");
        }
        return envBlock;
    }

    public static void LaunchAsCurrentUser(string cmdLine)
    {
        var process = Process.GetProcessesByName("explorer").FirstOrDefault();
        if (process != null)
        {
            var token = GetPrimaryToken(process);
            if (token != IntPtr.Zero)
            {
                var envBlock = GetEnvironmentBlock(token);
                if (envBlock != IntPtr.Zero)
                {
                    LaunchProcessAsUser(cmdLine, token, envBlock, process.SessionId);
                    if (!DestroyEnvironmentBlock(envBlock))
                    {
                        throw new Win32Exception(Marshal.GetLastWin32Error(), "DestroyEnvironmentBlock failed");
                    }
                }

                CloseHandle(token);
            }
        }
    }

    public static IDisposable ImpersonateCurrentUser()
    {
        var process = Process.GetProcessesByName("explorer").FirstOrDefault();
        if (process != null)
        {
            var token = GetPrimaryToken(process);
            if (token != IntPtr.Zero)
            {
                return Impersonate(token);
            }
        }

        throw new Exception("Could not find explorer.exe");
    }
}

You can use it like that:

ImpersonationUtils.LaunchAsCurrentUser("notepad");

using (ImpersonationUtils.ImpersonateCurrentUser())
{

}

More explanations and examples you can find here :

Impersonating CurrentUser from SYSTEM

这篇关于使用WindowsImpersonationContext访问网络驱动器模拟当前用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-20 20:09