模拟时获取当前用户名

我使用类似下面的方法来模拟我的代码中的用户:

你如何在.NET中进行模拟?

在另一个类中,我需要找出当前用户(如“mydomain \ moose”),但我不知道我是否正在模仿其他用户。

如果我冒充某人,我该如何获得用户名?

System.Environment.UserName和System.Security.Principal.WindowsIdentity.GetCurrent()。Name都返回原始用户,而不是当前模拟的用户。

更多细节:

我正在进行此模拟,以便我可以访问用户通常无权访问的netowrk共享中的某些文件。

如果我使用登录类型的LOGON32_LOGON_INTERACTIVE,我确实看到了新用户,但我无法访问网络共享。 如果我使用登录类型的LOGON32_LOGON_NEW_CREDENTIALS(值为9),我可以访问网络共享但我没有在Environment.UserName中看到新用户。

开始编辑:我意识到我第一次尝试回答这个问题并不是很清楚。 所以,我想开始另一次尝试:

首先,我想指出如果您使用LOGON32_LOGON_NEW_CREDENTIALSLOGON32_LOGON_INTERACTIVE作为LogonUser(在模拟类内部)函数的登录类型,属性WindowsIdentity.GetCurrent().Name将返回:

  1. 使用LOGON32_LOGON_INTERACTIVE

     // Assuming this code runs under USER_B using (var imp = new Impersonation("treyresearch", "USER_A", "SecurePwd", LOGON32_LOGON_INTERACTIVE )) { // Now, we run under USER_A Console.Out.WriteLine(WindowsIdentity.GetCurrent().Name); // Will return USER_A } 
  2. 使用LOGON32_LOGON_NEW_CREDENTIALS

     // Assuming this codes runs under USER_B using (var imp = new Impersonation("treyresearch", "USER_A", "SecurePwd", LOGON32_LOGON_NEW_CREDENTIALS )) { Console.Out.WriteLine(WindowsIdentity.GetCurrent().Name); // Will return USER_B } 

这是您在问题中描述的行为,并且与MSDN上LogonUser函数的描述一致。 对于LOGON32_LOGON_NEW_CREDENTIALS ,创建的用户令牌只是当前用户令牌的克隆。 这意味着创建的用户会话具有与调用线程相同的标识符。 传递给LogonUser函数的凭据仅用于出站网络连接。

其次,让我指出两种情况,即LOGON32_LOGON_INTERACTIVELOGON32_LOGON_NEW_CREDENTIALS之间描述的区别变得清晰:

  • 两个域加入的计算机:computer_A,computer_B
  • 两个用户:user_A(计算机_A上的本地管理员),user_B(仅B上的标准用户权限)
  • 计算机_B上的一个网络共享(mynetworkshare,user_B确实有权访问共享)。
  • computer_A上的一个本地文件夹(只有user_A有权写入此文件夹)。

您在computer_A上运行程序(在user_A帐户下)。 您模拟user_B(使用LOGON32_LOGON_INTERACTIVE )。 然后连接到computer_B上的网络共享并尝试将文件复制到本地文件夹(只有user_A有权写入此文件夹)。 然后,您会收到拒绝访问错误消息,因为文件操作是使用user_B的权限完成的,该权限对本地文件夹没有权限。

与上述情况相同。 但现在,我们使用LOGON32_LOGON_NEW_CREDENTIALS来模拟user_B。 我们连接到网络驱动器并将文件从网络驱动器复制到本地文件夹。 在这种情况下,操作成功,因为文件操作是使用user_A的权限完成的。

结束编辑

希望这可以帮助。

根据http://msdn.microsoft.com/en-us/library/chf6fbt4.aspx上的示例,当前身份在模拟期间会发生变化。 您确定您的代码在模拟代码块中吗?

我写了一个辅助类来完成它:

 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"); } } 

你可以像这样使用它:

 ImpersonationUtils.LaunchAsCurrentUser("notepad"); using (ImpersonationUtils.ImpersonateCurrentUser()) { } 

您可以在此处找到更多解释和示例:

模拟来自SYSTEM的CurrentUser

看一下QueryCredentialsAttributes