如何正确使用LogonUser从工作组客户端模拟域用户

Ric*_*iwi 40 .net c# impersonation winforms c#-2.0

ASP.NET:模拟VMWare上的域

这个问题就是我要问的问题,但答案并未提供有关_token如何派生的详细信息.它似乎只是使用WindowsIdentity.GetCurrent().Token所以没有冒充发生.

我可以在.NET中模拟其他Active Directory域上的用户吗?

接下来的问题有相互矛盾的答案,接受的答案是"我开始怀疑我的问题出在其他地方." 没用.

LogonUser仅适用于我的域

下一个问题似乎暗示它是不可能的,但它涉及2个域,所以我不确定它是否相关.

我真正的问题是:

  • 可能吗?如果是这样,
  • 怎么样?或者我哪里出错了?

我到目前为止尝试的是,使用http://msdn.microsoft.com/en-us/library/chf6fbt4%28v=VS.80%29.aspx中的代码

bool returnValue = LogonUser(user, domain, password,
            LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT,
            ref tokenHandle);
// after this point, returnValue = false
Run Code Online (Sandbox Code Playgroud)

Win32错误是

登录失败:未知的用户名或密码错误

tak*_*krl 58

很少有帖子建议使用LOGON_TYPE_NEW_CREDENTIALS而不是LOGON_TYPE_NETWORKLOGON_TYPE_INTERACTIVE.我有一个假冒问题,一台机器连接到一个域而一个没有,这就解决了.这篇文章中的最后一个代码片段表明模仿森林确实有效,但它没有具体说明建立信任的任何内容.所以这可能值得尝试:

const int LOGON_TYPE_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_WINNT50 = 3;
bool returnValue = LogonUser(user, domain, password,
            LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50,
            ref tokenHandle);
Run Code Online (Sandbox Code Playgroud)

MSDN说的是LOGON_TYPE_NEW_CREDENTIALS使用时只适用LOGON32_PROVIDER_WINNT50.

  • 请注意,`LOGON_TYPE_NEW_CREDENTIALS`在用于访问网络资源之前似乎不会验证凭据,因此它不能像`LOGON_TYPE_NETWORK`那样用于身份验证. (8认同)
  • 我有同样的问题冒充我的应用程序运行的域名.另一个域也没有信任.我会收到无意义的错误"系统找不到指定的文件".改变0,2到9,3就像你上面建议的那样工作!现在,我可以从不同域上的文件共享中读取文件.谢谢你,你救了我很多痛苦! (3认同)
  • 谢谢,它有效,但整个问题都很奇怪。我尝试在同一网络中进行身份验证以模拟,但在使用 LOGON32_LOGON_INTERACTIVE 时总是收到“未知用户名或密码错误”消息。在我的开发机器上一切正常。我很想追根溯源,但我该从哪里开始呢? (2认同)

JJ_*_*ire 21

这适用于我,完整的工作示例(我希望更多的人会这样做):

//logon impersonation
using System.Runtime.InteropServices; // DllImport
using System.Security.Principal; // WindowsImpersonationContext
using System.Security.Permissions; // PermissionSetAttribute

...

class Program {

    // obtains user token
    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
        int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

    // closes open handes returned by LogonUser
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    public extern static bool CloseHandle(IntPtr handle);

    public void DoWorkUnderImpersonation() {
        //elevate privileges before doing file copy to handle domain security
        WindowsImpersonationContext impersonationContext = null;
        IntPtr userHandle = IntPtr.Zero;
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_INTERACTIVE = 2;
        string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
        string user = ConfigurationManager.AppSettings["ImpersonationUser"];
        string password = ConfigurationManager.AppSettings["ImpersonationPassword"];

        try {
            Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);

            // if domain name was blank, assume local machine
            if (domain == "")
                domain = System.Environment.MachineName;

            // Call LogonUser to get a token for the user
            bool loggedOn = LogonUser(user,
                                        domain,
                                        password,
                                        LOGON32_LOGON_INTERACTIVE,
                                        LOGON32_PROVIDER_DEFAULT,
                                        ref userHandle);

            if (!loggedOn) {
                Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
                return;
            }

            // Begin impersonating the user
            impersonationContext = WindowsIdentity.Impersonate(userHandle);

            Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);

            //run the program with elevated privileges (like file copying from a domain server)
            DoWork();

        } catch (Exception ex) {
            Console.WriteLine("Exception impersonating user: " + ex.Message);
        } finally {
            // Clean up
            if (impersonationContext != null) {
                impersonationContext.Undo();
            }

            if (userHandle != IntPtr.Zero) {
                CloseHandle(userHandle);
            }
        }
    }


    private void DoWork() {
        //everything in here has elevated privileges

        //example access files on a network share through e$ 
        string[] files = System.IO.Directory.GetFiles(@"\\domainserver\e$\images", "*.jpg");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如何防止"密码"的内容在受损系统上通过内存转储或连接的调试器泄漏?我注意到你把它留在记忆中. (2认同)

Con*_*rad 1

我也遇到了同样的问题。不知道你是否已经解决了这个问题,但我真正想做的是使用 AD 凭据访问网络共享。WNetAddConnection2()是你在这种情况下需要使用的。