C# WindowsIdentity模拟方法在模拟管理员帐户时失败

C# WindowsIdentity模拟方法在模拟管理员帐户时失败,c#,.net,impersonation,C#,.net,Impersonation,我试图在.NET控制台应用程序中模拟用户帐户,当它达到我调用impersonate()方法的点时,应用程序似乎立即退出。方法调用位于try-catch块中,但它甚至从未到达“catch”块,因此我看不出错误是什么 以下是相关代码: [DllImport("advapi32.dll", SetLastError = true)] public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lp

我试图在.NET控制台应用程序中模拟用户帐户,当它达到我调用impersonate()方法的点时,应用程序似乎立即退出。方法调用位于try-catch块中,但它甚至从未到达“catch”块,因此我看不出错误是什么

以下是相关代码:

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
然后在我的申请开始时:

bool returnValue = LogonUser(user, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref m_tokenHandle);
if (!returnValue)
{
    int ret = Marshal.GetLastWin32Error();
    throw new System.ComponentModel.Win32Exception(ret);
}
// Impersonate
WindowsIdentity _identity = new WindowsIdentity(m_tokenHandle);
EmailHelper.SendErrorMessage("Windows Identity Created!", string.Format("Created at: {0}", DateTime.Now.ToLongTimeString()));
try
{
    m_impersonatedUser = _identity.Impersonate();
    EmailHelper.SendErrorMessage("Impersonation Complete...", string.Format("Impersonation at: {0}", DateTime.Now.ToLongTimeString()));
}
catch
{
    int ret = Marshal.GetLastWin32Error();
    EmailHelper.SendErrorMessage("Error impersonating user!", string.Format("Error: {0}", ret));
}
finally
{
    EmailHelper.SendErrorMessage("Finally block executed?!", "What is going on?");
}
我收到的是最初的“Windows身份创建”电子邮件,但不是其他任何电子邮件!有人知道我如何找出我的潜在错误是什么,以及为什么我的模拟不起作用吗

谢谢

编辑:

我尝试了这篇MSDN文章中的代码:唯一的修改是在模拟时尝试创建一个文件

修改正在更改此代码:

using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
    // Check the identity.
    Console.WriteLine("After impersonation: " + WindowsIdentity.GetCurrent().Name);
}
致:

作为“标准”用户运行exe时得到的输出表明LogonUser成功,WindowsIdentity.GetCurrent()。Name返回模拟用户名,但创建文件失败,错误代码为1346,根据MSDN,为:

错误\u错误\u模拟\u级别 1346(0x542) 未提供所需的模拟级别,或者提供的模拟级别无效

这是什么意思?谷歌还没能对此做出任何解释

编辑2:


我可以使用此代码模拟另一个标准用户帐户,但当我尝试模拟我的管理员帐户时失败。是否可以以某种方式更改代码以允许运行此exe的标准用户模拟管理员帐户?

当我运行您的代码时,我将所有发送电子邮件的呼叫替换为
控制台。WriteLine
,并使用我的UPN创建Windows标识。这导致调用try块,然后调用finally块,正如预期的那样

您的电子邮件发送方法可能存在问题。我想看看你是否得到了与我用
Console.WriteLine()
替换后相同的结果。
还可以尝试在末尾添加一个
Console.ReadLine()
,这样您就可以在不退出应用程序的情况下看到发生了什么。这可能是因为它工作正常,而你只是没有收到电子邮件。如果电子邮件工作正常,如果在那之后没有线路可呼叫,应用程序将立即退出,但您仍然会收到一封电子邮件。

您是否测试了
m_tokenHandle

if (m_tokenHandle != IntPtr.Zero)
{
  // continue on
您是否测试了身份信息?也没有测试

if (_identity != null)
{
  // continue on

无论try例程是否成功,finally块都将执行。

遗憾的是,这似乎仍然不起作用,我有一种预感,即使用WindowsIdentity模拟管理员帐户可能不受支持,或者我的方法有缺陷。不管是哪种方式,我决定完全采用另一种方法,将我想作为管理员运行的代码放在一个单独的可执行文件中,然后使用管理员凭据将该可执行文件作为一个新进程启动

System.Diagnostics.Process.Start(myExecutablePath, args, adminUsername, adminPassword, domainName);

这很好,因此可能任何遇到此问题的人也可以使用此解决方法。

你好,Savanna,感谢您在您的终端进行测试。我应该给出一点上下文:这段代码的目的是将一些文件从服务器复制到本地计算机,否则用户无法访问这些文件,因此我需要模拟来作为管理员复制这些文件。起初,电子邮件代码不存在,而是写入日志文件,但我用电子邮件代码替换了它,因为我认为这是一个权限问题。无论哪种方式,在Visual Studio中运行代码都是可行的,但部署代码并以用户身份运行可执行文件是在我获得我所描述的行为时进行的。当我以用户身份运行可执行文件时,我收到了最初的电子邮件,但没有收到其他电子邮件,即使是finally块中的电子邮件也没有收到。日志文件正在工作,但只有在Visual Studio中运行时才起作用。以用户身份运行exe甚至没有创建日志文件,这就是为什么我将其替换为电子邮件代码,认为这是权限问题。我发布的代码位于类库中,而我正在运行的可执行文件实际上只调用该类库中的方法。这会有所不同吗?你说你的UPN是什么意思?LogonUser正在返回true,这不意味着它已正确通过身份验证吗?您可以通过几种方式创建WindowsIdentity。我用一个代表我自己用户名的字符串创建了这个。所以我是在假装自己。我不确定m_tokenHandle对您来说是什么。我猜该标记句柄是有效的,因为LogonUser返回一个成功(我也可以在我的事件查看器中看到登录成功)。我只是尝试使用DuplicateToken生成一个不同的令牌并使用它创建WindowsIdentity,这似乎做了完全相同的事情。您好jp2code,我尝试添加一些代码向我发送一封关于值的电子邮件,m_tokenHandle不等于IntPtr。零和_identity也不为null。该代码在Visual Studio中运行(在我的管理员帐户下运行)时有效(通过了try-catch),但在以用户身份执行时无效,我认为这就是问题所在,但finally块中的代码没有执行,因为应用程序似乎没有走那么远!您可能需要让网络人员为您的电脑设置一个管理员帐户。然后,在调用代码之前模拟该帐户。请参阅。我模拟的帐户是管理员帐户,但运行exe的帐户是标准用户帐户。也许用户帐户需要一些额外的权限,以允许我的代码模拟管理员帐户?请显示一些代码,以揭示什么是“在使用中创建文件”。如果您写入错误的位置或使用错误的代码,那么错误代码并不奇怪。嗨,Lex Li,我编辑了我的问题以显示我添加的代码。当尝试模拟管理员帐户时,应用程序不会创建文件,而是将“模拟后”行写入cons
System.Diagnostics.Process.Start(myExecutablePath, args, adminUsername, adminPassword, domainName);