【问题标题】:Impersonate with username and password?冒充用户名和密码?
【发布时间】:2011-12-04 08:42:32
【问题描述】:
WindowsIdentity identity = new WindowsIdentity(accessToken);
WindowsImpersonationContext context = identity.Impersonate();

 ...
context.Undo();

我在哪里声明管理员用户名和密码?

accessToken 参数对我没有太大帮助...

我必须为它导入 DLL'S 吗?

【问题讨论】:

    标签: c# console-application impersonation


    【解决方案1】:

    您需要获取用户的令牌。使用 advapi32.dll 中的 p/invoke LogonUser

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LogonUser(
                string lpszUsername,
                string lpszDomain,
                string lpszPassword,
                int dwLogonType,
                int dwLogonProvider,
                out IntPtr phToken);
    

    示例:

    IntPtr userToken = IntPtr.Zero;
    
    bool success = External.LogonUser(
      "john.doe", 
      "domain.com", 
      "MyPassword", 
      (int) AdvApi32Utility.LogonType.LOGON32_LOGON_INTERACTIVE, //2
      (int) AdvApi32Utility.LogonProvider.LOGON32_PROVIDER_DEFAULT, //0
      out userToken);
    
    if (!success)
    {
      throw new SecurityException("Logon user failed");
    }
    
    using (WindowsIdentity.Impersonate(userToken))
    {
      // do the stuff with john.doe's credentials
    }
    

    【讨论】:

    • 有没有办法不用密码?我可以访问它,因为我正在模仿之前创建,只是想我会问。
    • 我想应该在 using 块之后为 userToken 调用 CloseHandle(如 docs for LogonUser 中所述)。或者这是WindowsIdentity以某种方式调用的?
    • 嗨,如果这是 ASP.NET 应用程序,它的范围是什么?我应该在每个页面中调用这个函数吗?
    • 您可能希望使用此代码而不是抛出 SecurityException 来很好地获取错误详细信息: throw new Win32Exception(Marshal.GetLastWin32Error())
    【解决方案2】:

    它正是您必须使用的访问令牌。要获取它,您需要调用 LogonUser 方法:

    哎呀没有意识到我只是在这里有 VB.net 代码。在 C# 中想象它;) 在这里c#

    外部方法声明:

    Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
    ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
    ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
    ByRef phToken As IntPtr) As Boolean
    

    和执行:

    _Token = New IntPtr(0)
    
    Const LOGON32_PROVIDER_DEFAULT As Integer = 0
    'This parameter causes LogonUser to create a primary token.
    Const LOGON32_LOGON_INTERACTIVE As Integer = 2
    Const LOGON32_LOGON_NEWCREDENTIALS As Integer = 9
    
    _Token = IntPtr.Zero
    
    ' Call LogonUser to obtain a handle to an access token.
    Dim returnValue As Boolean = LogonUser(_User, _Domain, _Password, LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, _Token)
    
    If False = returnValue Then
         Dim ret As Integer = Marshal.GetLastWin32Error()
         Console.WriteLine("LogonUser failed with error code : {0}", ret)
         Throw New System.ComponentModel.Win32Exception(ret)
    End If
    
    _Identity = New WindowsIdentity(_Token)
    _Context = _Identity.Impersonate()
    

    【讨论】:

      【解决方案3】:

      您需要 P/invoke LogonUser() API。它接受用户名、域和密码并返回一个令牌。

      【讨论】:

        猜你喜欢
        • 2013-10-03
        • 2014-12-07
        • 2016-05-10
        • 2017-05-18
        • 2010-11-29
        • 2012-07-29
        • 2016-03-16
        • 2019-03-02
        • 1970-01-01
        相关资源
        最近更新 更多