【问题标题】:Impersonate local user on another machine在另一台机器上模拟本地用户
【发布时间】:2017-05-01 15:55:59
【问题描述】:

我需要将我的控制器登录到另一台机器并在上面复制一个文件;我必须在远程机器上使用本地用户。

目前我正在使用此代码:

    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))
    {

    }  

还有这个 win 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,但即使没有记录,它也总是返回正常。

【问题讨论】:

    标签: c# dllimport impersonation


    【解决方案1】:

    我终于解决了这个问题,无需将用户添加到将模拟远程机器的每台机器。

    使用 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))
    {
    
    }
    

    【讨论】:

    • LOGON32_PROVIDER_WINNT50 单独对我不起作用。我什至尝试了几种登录类型。尝试使用远程计算机上的本地用户访问远程文件夹时,我仍然收到“用户或密码不正确”。如果传递了域(根据文档),LOGON32_PROVIDER_WINNT50 与 LOGON32_PROVIDER_DEFAULT 的作用相同。如果您的代码确实有效,那么您共享的代码中肯定有其他内容不可见。您能否分享整个代码和调用?
    • @JürgenBayer 添加了使用模拟方法的代码,该代码运行良好
    【解决方案2】:

    您可以尝试在本地计算机上使用与远程服务器上的本地用户相同的用户名和密码来创建本地用户。

    【讨论】:

    • 谢谢,但我无法将用户复制到场中的每台机器上;如果您查看我的答案,我会找到避免它的解决方案。
    猜你喜欢
    • 2011-04-04
    • 2017-01-15
    • 2021-12-03
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-05
    相关资源
    最近更新 更多