【发布时间】:2020-04-05 23:57:11
【问题描述】:
在 .Net Core 下使用模拟时,我似乎无法以其他用户身份启动进程。
我正在以 User1 身份运行的 Linqpad 中运行此脚本,并尝试以 User2 身份启动程序。
起初,模拟似乎有效(当前用户上的Console.Writeline()s 在RunImpersonated() 方法中从User1 正确更改为User2)。但是,该进程始终以 User1 身份运行。
这是我为验证RunImpersonated() 是否有效而进行的众多测试之一(这最初源于试图模拟当前用户的 ASP.Net Core 应用程序中的问题)。这是我能找到的最简单的可重现示例。
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);
void Main()
{
string domainName = "myDomain";
string userName = "User2";
string passWord = "User2Password";
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
SafeAccessTokenHandle safeAccessTokenHandle;
bool returnValue = LogonUser(userName, domainName, passWord,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new System.ComponentModel.Win32Exception(ret);
}
Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
// Check the identity.
Console.WriteLine("Before impersonation: " + WindowsIdentity.GetCurrent().Name);
// Note: if you want to run as unimpersonated, pass
// 'SafeAccessTokenHandle.InvalidHandle' instead of variable 'safeAccessTokenHandle'
WindowsIdentity.RunImpersonated(
safeAccessTokenHandle,
// User action
() =>
{
// Check the identity.
Console.WriteLine("During impersonation: " + WindowsIdentity.GetCurrent().Name);
Directory.GetFiles(@"C:\TMP\").Dump();
var pi = new ProcessStartInfo
{
WorkingDirectory = @"C:\TMP\",
FileName = @"C:\TMP\TestUser.exe"
};
var proc = Process.Start(pi);
proc.WaitForExit();
}
);
// Check the identity again.
Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
}
【问题讨论】:
-
设置
ProcessStartInfo对象的UserName和Password属性是否有效? -
我使用
Process.Start并在另一个凭据下运行应用程序没有任何问题。 -
@Progman 目标不是运行另一个进程,这是我们可以制作的最小可复制项目,其中在模拟上下文中运行的代码不会表现得像怀疑的那样,在实际场景中我们并没有尝试运行另一个程序,我们可以访问要模拟的令牌,但不能访问登录名/密码。目标是了解为什么这不起作用以及如何使其起作用以避免在这里提出一个很长的问题,因为这似乎是最简单的情况,但我们需要知道为什么它不能按原样起作用以及如何做到这一点通过模拟在线程级别工作,而不是进程启动
-
@RezaAghaei 虽然将凭据传递给进程很容易,但在这里我们尝试在模拟上下文中不传递任何内容的情况下执行此操作,期望它以模拟用户身份运行,而不是它以原始用户身份运行
-
直接运行 Process.Start(@"C:\TMP\TestUser.exe");
标签: c# asp.net-core .net-core impersonation windows-identity