none
Execute Process() in context of current user (WCF Service, Kerberos) RRS feed

  • Question

  • I’m consulting for a company where they desire to execute a script/executable under the calling user context when invoked through a WCF service. All the relevant infrastructure is running on Windows 2012 with Kerberos configured (which works on other applications).

    What are we trying to achieve?

    Web service (WCF) executing (python) scripts/executable under the context of the calling user. The WCF service application pool is configured with a service account which has delegation rights on behalf of the calling user(s).

    Limitations:

    -          Cannot store user token and/or credentials (securely in memory during execution is fine)

    Current flow

    1. User invoke the WCF Service (with the current user credentials (domain/username))
    2. The WCF service executes a script/executable (controlled by us) in context of the above-mentioned service account (which has delegation turned on but doesn’t work).

    Desired flow

    1. User invoke the WCF Service (with the current user credentials (domain/username)) – SAME AS CURRENT FLOW
    2. The WCF service executes the script/executable in the current user context.

    Code samples

    WCF Service

    Lots of code omitted for brevity and there might be some best practices being violated. Never mind that, this is just example-/pseudo code.

    public Stream GetScript(string key)

    {

        var currentIdentity = WindowsIdentity.GetCurrent();

     

        using (currentIdentity.Impersonate())

        {

            result = ExecuteScript();

        }

        var ms = new MemoryStream(); // from the above result, not important

        return ms;

    }

    private string ExecuteScript()

    {

        string result;

        var currentIdentity = WindowsIdentity.GetCurrent();

        using (var process = new Process())

        {

            var executablePath = @" executable.exe";

            var workingDirectoryPath = @"c:\somedirectory";

            var name = currentIdentity.Name;

            var token = currentIdentity.Token.ToString();

            result = $"Name: {name}, Token: {token}{Environment.NewLine}{Environment.NewLine}";

            currentIdentity.Impersonate();

            var startInfo = new ProcessStartInfo {

                    FileName = executablePath,

                    WorkingDirectory = workingDirectoryPath,

                    UseShellExecute = false,

                    RedirectStandardOutput = true,

                    RedirectStandardError = true

            };

                   

            process.StartInfo = startInfo;

            process.Start();

            while (!process.StandardOutput.EndOfStream)

                result += $", Result: {process.StandardOutput.ReadLine()}";

        }

        return result;

    }

    Script/Command line application

    Again, not production code, so I’ve omitted code for brevity.

    private static void Main(string[] args)

    {

        var currentIdentity = WindowsIdentity.GetCurrent();

        using (currentIdentity.Impersonate()) {

             Console.WriteLine(WindowsIdentity.GetCurrent().Name);

        }

    }

    Any thoughts of places I can do changes/investigate in order to get the script/executable to run under the user’s context?

    Monday, April 9, 2018 6:09 AM

All replies

  • Hi Rodahl,

    >> The WCF service application pool is configured with a service account which has delegation rights on behalf of the calling user(s)

    Do you run the WCF under LocalService or NetworkService?

    >> var currentIdentity = WindowsIdentity.GetCurrent();

    If you check the Name of currentIdentity, will it be the user account name?

    Do you use wsHttpBinding? Will configuration below meet your requirement?

    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string GetData(int value)
    {
      return string.Format("Hi, {0}, you have entered: {1}",
                               WindowsIdentity.GetCurrent().Name, value);
    }

    # How to: Impersonate the Original Caller in WCF Calling from a Web Application

    https://msdn.microsoft.com/en-us/library/ff650591.aspx

    Best Regards,

    Tao Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, April 10, 2018 2:52 AM