在另一台机器上模拟本地用户
Impersonate local user on another machine
我需要将我的控制器登录到另一台机器上并在上面复制一个文件;我必须在远程机器上使用本地用户。
目前我正在使用这个代码:
private Impersonate(bool active, string domain, string username, string password, LogonType logonType)
{
if (active)
{
IntPtr handle;
var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, 0, out handle);
if (!ok)
{
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
}
_handle = new SafeTokenHandle(handle);
_context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
}
}
传递这些参数:
using (Impersonate.LogonUser(true,
".",
"todev1.domain.com\admin",
"Test123_",
LogonType.Interactive))
{
}
并且这场胜利 API:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
我检查了这个 Q/A Using advapi32.dll:LogonUserA() to impersonate a remote machine's local user 但提供的解决方案不起作用。
我试图将多个值作为域、用户等传递给该方法,但我找不到正确的解决方案。我尝试使用 NewCredentials 但它 returns 即使没有记录也总是可以的。
您可以尝试在本地计算机上创建一个本地用户,使用与远程服务器上的本地用户相同的用户名和密码。
我终于解决了这个问题,不需要将用户添加到每台将模拟远程机器的机器上。
使用NewCredential是正确的,但是使用的是WINNT50 LogonProvider。
所以我现在的模拟方法是这样的:
private Impersonate(bool active, string domain, string username, string password, LogonType logonType, LogonProvider logonProvider)
{
if (active)
{
IntPtr handle;
var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, (int)logonProvider, out handle);
if (!ok)
{
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
}
_handle = new SafeTokenHandle(handle);
_context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
}
}
然后我使用代码调用 Impersonate 方法:
using (Impersonate.LogonUser(true,
"todev1.domain.com",
"admin",
"Test123_",
LogonType.NewCredentials,
LogonProvider.WinNT50))
{
}
我需要将我的控制器登录到另一台机器上并在上面复制一个文件;我必须在远程机器上使用本地用户。
目前我正在使用这个代码:
private Impersonate(bool active, string domain, string username, string password, LogonType logonType)
{
if (active)
{
IntPtr handle;
var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, 0, out handle);
if (!ok)
{
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
}
_handle = new SafeTokenHandle(handle);
_context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
}
}
传递这些参数:
using (Impersonate.LogonUser(true,
".",
"todev1.domain.com\admin",
"Test123_",
LogonType.Interactive))
{
}
并且这场胜利 API:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
我检查了这个 Q/A Using advapi32.dll:LogonUserA() to impersonate a remote machine's local user 但提供的解决方案不起作用。
我试图将多个值作为域、用户等传递给该方法,但我找不到正确的解决方案。我尝试使用 NewCredentials 但它 returns 即使没有记录也总是可以的。
您可以尝试在本地计算机上创建一个本地用户,使用与远程服务器上的本地用户相同的用户名和密码。
我终于解决了这个问题,不需要将用户添加到每台将模拟远程机器的机器上。
使用NewCredential是正确的,但是使用的是WINNT50 LogonProvider。
所以我现在的模拟方法是这样的:
private Impersonate(bool active, string domain, string username, string password, LogonType logonType, LogonProvider logonProvider)
{
if (active)
{
IntPtr handle;
var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, (int)logonProvider, out handle);
if (!ok)
{
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
}
_handle = new SafeTokenHandle(handle);
_context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
}
}
然后我使用代码调用 Impersonate 方法:
using (Impersonate.LogonUser(true,
"todev1.domain.com",
"admin",
"Test123_",
LogonType.NewCredentials,
LogonProvider.WinNT50))
{
}