Either a required impersonation level was not provided, or the provided impersonation level is invalid

Martin Clarke picture Martin Clarke · Sep 4, 2012 · Viewed 20.5k times · Source

I'm having some issues with a WCF service and Impersonation, I've distilled this to a simple method below. The WCF service is currently self hosted in an exe. The exception message is "Either a required impersonation level was not provided, or the provided impersonation level is invalid". Checking when the error is thrown, the Identity ImpersonationLevel is set to delegation, as specified on my client and its authenticated through Kerberos.

I'm a bit puzzled, as it seems to me that the requirements of ImpersonationLevel and Authenticaiton have been met. My thinking is that the issue is probably to do with domain settings, which I've set and think are set correctly. So I have two questions:

  1. Should the operation below succeed? (or is it flawed?)
  2. What settings needs to be configured on a Win2k8 domain to make it work? I'm working of two boxes that are members of the same Win2k8 domain (its a new domain and pretty vanilla, with the intention of testing Impersonation).

Code as follows:

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string Test()
{
    WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;
    using (identity.Impersonate())
    {
        ProcessStartInfo pi = new ProcessStartInfo(@"c:\temp\test.bat");
        pi.UseShellExecute = false;
        pi.RedirectStandardOutput = true;
        Process p = Process.Start(pi); // exception thrown here!
        p.WaitForExit();
        string o = p.StandardOutput.ReadToEnd();
        return o;
    }
}

Exception details:

Win32Exception occurred: Either a required impersonation level was not provided, or the provided impersonation level is invalid
   at System.Diagnostics.Process.CreatePipeWithSecurityAttributes(SafeFileHandle& hReadPipe, SafeFileHandle& hWritePipe, SECURITY_ATTRIBUTES lpPipeAttributes, Int32 nSize)
   at System.Diagnostics.Process.CreatePipe(SafeFileHandle& parentHandle, SafeFileHandle& childHandle, Boolean parentInputs)
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at MonetEnterprise.Service.SecurityService.Test()

Test.bat file contents

echo %username%

Answer

Martin Clarke picture Martin Clarke · Sep 6, 2012
  1. It is flawed as long as you're using the .NET Process class, it will always start with the identity of the parent process. To run it under another identity it looks like you've got to use the win32 api CreateProcessAsUser (which I've not got working yet).

  2. I needed to run it elevated (i.e. Visual Studio as Administrator).