【问题标题】:Help Understanding Impersonation帮助了解模拟
【发布时间】:2011-05-22 16:17:40
【问题描述】:

我正在寻找一种使用 C# 代码启动/停止驻留在远程计算机中的 Windows 服务的方法,并找到了以下代码示例。这对我来说可以。它是使用模拟技术编码的,这显然要求两台机器(比如说 A 和 B)都有一个具有相同 UserName + Password 组合的用户帐户。

int LOGON32_LOGON_INTERACTIVE = 2;
int LOGON32_PROVIDER_DEFAULT = 0;

private bool impersonateValidUser(String userName, String machineName, String passWord)
    {
      WindowsIdentity tempWindowsIdentity;
      IntPtr token = IntPtr.Zero;
      IntPtr tokenDuplicate = IntPtr.Zero;

      if (RevertToSelf())
      {
        if (LogonUserA(userName, machineName, passWord, 
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
        {
          if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
          {
            tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
            impersonationContext = tempWindowsIdentity.Impersonate();
            if (impersonationContext != null)
            {
              CloseHandle(token);
              CloseHandle(tokenDuplicate);
              return true;
            }
          }
        }
      }
      if (token != IntPtr.Zero)
      {
        CloseHandle(token);
      }
      if (tokenDuplicate != IntPtr.Zero)
      {
        CloseHandle(tokenDuplicate);
      }

      return false;
    }

现在我需要知道以下问题的答案,如果有人能帮助我,我将不胜感激。

  1. 对代码的一般解释。

  2. 为什么两台机器的用户帐户必须具有相同的用户名+密码组合?

  3. 为什么两个用户帐户(Admin 或 Non-Admin)的权限无关?

提前谢谢你。

【问题讨论】:

  • 此代码无法编译。您的线路 impersonationContext = tempWindowsIdentity.Impersonate(); 必须是 WindowsImpersonationContext impersonationContext = tempWindowsIdentity.Impersonate();。在if (impersonationContext != null) { ... } 中,您可以作为其他帐户进行工作。
  • 更好的方法是让这个函数返回 WIC,这样您就可以在别处工作,并在完成后调用另一个函数来关闭您的令牌句柄。看看我在这里做了什么:stackoverflow.com/questions/1335065/…

标签: c# windows windows-services impersonation remote-access


【解决方案1】:

下面是关于模拟的一个很好的一般解释:A .NET Developer's Guide to Windows Security: Understanding Impersonation

1) 代码的作用是“以用户身份登录”。这里的中心 API 是 LogonUser(本机调用)和 Impersonate() (.NET),记录在此处:http://msdn.microsoft.com/en-us/library/aa378184(VS.85).aspx 和此处:http://msdn.microsoft.com/en-us/library/w070t6ka.aspx

其余的或多或少需要管道。

2) 这不是必需的,但我想这就是您的基础架构中选择的内容,因为机器可能不在同一个帐户域中,或者根本没有帐户域。在这种情况下,相同的帐户名+密码是一个老把戏。如果机器在同一个 Windows 域 (AD) 中,则不需要。

3) 模拟不需要管理员权限(如果我没记错的话,仅适用于 Windows 2000 及更早版本)

【讨论】:

  • 西蒙,非常感谢您的回复。所以让我看看我是否做对了。
  • Re 1. 假设我们有运行 ServiceA 的机器 A。我有机器 B,我想从中启动/停止 ServiceA。我正在开发的应用程序现在运行在机器 B 上。所以,当我使用 LogonUser 方法时,它会登录到机器 B 中的给定用户帐户,对吗?那么,Impersonate() 方法做了什么?
  • Re 2. 我尝试从具有不同凭据的 MachineB 中的用户帐户访问 ServiceA,但它失败了。您能否提供一个代码示例,我可以在远程机器上启动/停止服务,而不必在两台机器上使用相同的用户名+密码组合?
  • 关于 SO 的讨论解释了如何使用非托管 Windows API 安装/启动/停止服务:stackoverflow.com/questions/358700/…
  • 我意识到这是一篇旧帖子,但为了所有可能谷歌的利益并找到这个:如果您有一个具有管理员权限的帐户,则该服务在哪个帐户下运行并不重要机器 A。当您使用 LogonUser() 方法时,您向该方法发送您要使用的帐户的凭据,也就是机器 A 上的 Admin 帐户。所有该功能提供的只是 IntPtr phToken 回。然后,您复制该令牌并为其分配模拟级别安全标志(您给它的那个数字 2 意味着)。然后,您将使用重复的令牌创建 WindowsIdentity
猜你喜欢
  • 2011-05-06
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 2017-06-19
  • 2016-05-03
  • 2011-07-28
  • 1970-01-01
  • 2021-01-18
相关资源
最近更新 更多