C#User Impersonation未传递给子流程

时间:2017-05-12 16:42:23

标签: c# wcf wcf-security

我正在尝试模拟用户从控制台应用程序运行的所有进程。我不想以该用户身份启动我的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用户名而不是模拟用户。

我的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();

我正在尝试实现以下代码所做的事情,但在调试模式下运行app并且不更改任何当前的wcf配置。

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

我知道将整个应用程序作为用户运行和模拟应用程序内的用户之间存在差异。但只是想看看是否有人有类似的问题,并设法找到解决方案。

修改1:

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

1 个答案:

答案 0 :(得分:0)

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