C#未将用户模拟传递到子进程

C#未将用户模拟传递到子进程,c#,wcf,wcf-security,C#,Wcf,Wcf Security,我正在尝试模拟从控制台应用程序运行的所有进程的用户。我不想以该用户的身份启动VisualStudio,也不想继续连接在该用户下运行的外部进程 这就是我尝试过的 static void Main(string[] args) { Console.WriteLine("Environment.UserName: {0}", Environment.UserName); // Prints currently logged-in win usern

我正在尝试模拟从控制台应用程序运行的所有进程的用户。我不想以该用户的身份启动VisualStudio,也不想继续连接在该用户下运行的外部进程

这就是我尝试过的

       static void Main(string[] args)
        {
            Console.WriteLine("Environment.UserName: {0}", Environment.UserName); // Prints currently logged-in win username

            ConfigurationManager.GetSection("configuration");                    

            using (var impersonator = new Impersonator())
            {
                Console.WriteLine("Environment.UserName: {0}", Environment.UserName); // Prints impersonated username

                var hostAccount = new System.ServiceModel.ServiceHost(typeof(AccountService));  // WCF Service class            
                hostAccount.Open();
            }
        }
若我尝试在AccountService类的任何方法中检查Environment.UserName的值,它总是给我当前登录的win UserName,而不是模拟用户

My Impersonator类使用以下代码来模拟用户

bool returnValue = LogonUser(user, userDomain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref _userHandle);

if (!returnValue)
    throw new ApplicationException("Could not impersonate user");

WindowsIdentity newId = new WindowsIdentity(_userHandle);
_impersonatedUser = newId.Impersonate();
我试图实现以下代码的功能,但在调试模式下运行应用程序,并且不更改任何当前wcf配置

Process.Start("path to exe", "user", ssPwd, "MyDOMAIN");
我知道作为用户运行整个应用程序和在应用程序中模拟用户之间有区别。但我只是想看看是否有人有类似的问题,并设法找到了解决办法

编辑1:

我尝试在模拟用户后启动新线程,它们都在模拟用户下运行。所以新线程确实会得到模拟的上下文。我想这与wcf主机的启动方式有关。

wcfhost.open()总是在主用户标识下运行,而不是在模拟标识下运行。所以现在我在另一个控制台应用程序的不同用户下启动我的主控制台应用程序,并将调试器附加到它,它就可以工作了

我已经复制了下面的代码,如果它对任何人都有帮助的话

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security;
using EnvDTE80;
using Process = System.Diagnostics.Process;

namespace StartService
{
    class Program
    {
        static void Main(string[] args)
        {
            var secure = new SecureString();
            foreach (var c in "password-from-config")
            {
                secure.AppendChar(c);
            }

            Process process = null;

            try
            {
                process = Process.Start(@"C:\Test Projects\WcfServiceTest\WcfServiceTest\bin\Debug\WcfServiceTest.exe",
                    "TestUser", secure, "DomainName");

                Attach(GetCurrent());

                Console.ReadKey();
            }
            finally
            {
                if (process != null && !process.HasExited)
                {
                    process.CloseMainWindow();
                    process.Close();
                }    
            }
        }

        public static void Attach(DTE2 dte)
        {
            var processes = dte.Debugger.LocalProcesses;
            foreach (var proc in processes.Cast<EnvDTE.Process>().Where(proc => proc.Name.IndexOf("WcfServiceTest.exe") != -1))
                proc.Attach();
        }

        internal static DTE2 GetCurrent()
        {
            var dte2 = (DTE2)Marshal.GetActiveObject("VisualStudio.DTE.12.0"); // Specific to VS2013

            return dte2;
        }
    }
}
使用系统;
使用System.Linq;
使用System.Runtime.InteropServices;
使用系统安全;
使用EnvDTE80;
使用过程=System.Diagnostics.Process;
名称空间StartService
{
班级计划
{
静态void Main(字符串[]参数)
{
var secure=new SecureString();
foreach(配置中的密码中的变量c)
{
安全的。附加字符(c);
}
Process=null;
尝试
{
process=process.Start(@“C:\Test Projects\WcfServiceTest\WcfServiceTest\bin\Debug\WcfServiceTest.exe”,
“TestUser”,安全,“域名”);
附加(GetCurrent());
Console.ReadKey();
}
最后
{
if(process!=null&&!process.HasExited)
{
process.CloseMainWindow();
process.Close();
}    
}
}
公共静态无效附加(DTE2 dte)
{
var processs=dte.Debugger.localprocesss;
foreach(processs.Cast()中的var proc,其中(proc=>proc.Name.IndexOf(“WcfServiceTest.exe”)!=-1))
过程附加();
}
内部静态DTE2 GetCurrent()
{
var dte2=(dte2)Marshal.GetActiveObject(“VisualStudio.DTE.12.0”);//特定于VS2013
返回dte2;
}
}
}

我很困惑-你是说
hostAccount.Open()
创建了一个新进程,但没有捕获模拟上下文?如果是的话,这是意料之中的。事实上,这是在操作系统级别发生的,而不是CLR:默认情况下,Windows不会捕获调用进程甚至调用线程的SecurityContext(包括标识信息)。您必须以某种方式将模拟令牌传递给新进程,然后在那里运行
.Impersonate()
。@PoweredByOrange“我很困惑-您是说
hostAccount.Open()
创建了一个新进程,但没有捕获模拟上下文?”是的。“默认情况下,Windows不会捕获调用进程甚至调用线程的SecurityContext(其中包括身份信息)。”如果这是真的,那么它只能用于模拟上下文,否则
process.Start(“exe路径”、“用户”、ssPwd、“MyDOMAIN”)
也会有同样的问题。@PoweredByOrange“您必须以某种方式将模拟令牌传递给新进程并在那里运行.Impersonate()。”这应该可以工作,但我有许多主机和其他进程是从主方法开始的(为了简单起见,我已经从问题中删除了其余的代码)所以我不想到处传播模拟代码。看看。它允许您使用模拟令牌启动进程。@PoweredByOrange谢谢,但它与
process.start(“path to exe”,“user”,ssPwd,“MyDOMAIN”)有何不同?我不想传递
lpApplicationName