C# 用户模拟未传递给子进程 [英] C# User Impersonation not being passed on to sub-processes

查看:27
本文介绍了C# 用户模拟未传递给子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to impersonate user for all the processes running from a console app. I don't want to start my VisualStudio as that user nor want to keep attaching external process running under that user.

这是我尝试过的...

       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 用户名而不是模拟用户.

If I try to inspect value of Environment.UserName inside any method of AccountService class, it always gives me currently logged-in win username instead of impersonated user.

我的 Impersonator 类使用以下代码来模拟用户.

My Impersonator class uses following code to impersonate user.

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 配置.

I am trying to achieve something what the following code does but running app in debug mode and without changing any current wcf config.

Process.Start("path to exe", "user", ssPwd, "MyDOMAIN");

我确实理解以用户身份运行整个应用程序和在应用程序内模拟用户之间存在差异.但只是想看看是否有人遇到了类似的问题并设法找到了解决方案.

I do understand there is difference between running the whole app as an user and impersonating an user inside app. But just want to see if someone had similar issue and managed to find a solution.

编辑 1:

我尝试在模拟用户后启动新线程,并且它们都在模拟用户下运行.因此,新线程确实会获得模拟上下文.我想这与 wcf 主机的启动方式有关.

I have tried starting new threads after impersonating a user and they all were running under impersonated user. So new threads do get impersonated context. I guess it has something to do with how wcf host gets started.

推荐答案

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

wcfhost.open() always runs under main user identity and not under impersonated identity. So now I am starting my main console app under different user from another console app and attaching debugger to it and it works.

如果对任何人有帮助,我已在下面复制了我的代码.

I have copied my code below if it helps anyone.

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;
        }
    }
}

这篇关于C# 用户模拟未传递给子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆