title: Impersonation using WCF
body: <p>I am trying to expose via WCF Web services, functions that access SQL server (via Entity Framework) using the user's credentials (this is a client/dba requirement because of audit triggers etc. Gave up trying to convince them not to use user's credentials)</p>
  
  <p>I am having trouble getting WCF to implement impersonation. (in fact its been a nightmare). I have added the</p>
  
  <pre><code>[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
  </code></pre>
  
  <p>attribute to my contract. But then it complained about BasicHttpContract not being able to do Window Impersonation. I've tried to change it to wsHttpBinding. Now the Metadata exchange is broken. So far, I am only trying to open the services in internet explorer, haven't even started connecting to it with the client yet. The relevant section of the web.config looks like below</p>
  
  <pre><code>&lt;behaviors&gt;
    &lt;serviceBehaviors&gt;
      &lt;behavior name="AssetManagerBehavior"&gt;
        &lt;serviceAuthorization impersonateCallerForAllOperations="true" /&gt;
        &lt;!--
        --&gt;
        &lt;!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment --&gt;
        &lt;serviceMetadata httpGetEnabled="true" /&gt;
        &lt;!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information --&gt;
        &lt;serviceDebug includeExceptionDetailInFaults="true" /&gt;
      &lt;/behavior&gt;
    &lt;/serviceBehaviors&gt;
  &lt;/behaviors&gt;
  &lt;serviceHostingEnvironment multipleSiteBindingsEnabled="true" /&gt;
  
      &lt;services&gt;
          &lt;service name="AssetManager.ServiceInterface" behaviorConfiguration="AssetManagerBehavior"&gt;
              &lt;endpoint  address="" binding="wsHttpBinding" contract="IAssetServices"&gt;
              &lt;/endpoint&gt;
      &lt;endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/&gt; 
          &lt;/service&gt;
      &lt;/services&gt;
  
  &lt;bindings&gt;
    &lt;wsHttpBinding&gt;
      &lt;binding name="test"&gt;
        &lt;security mode="TransportWithMessageCredential" /&gt;
      &lt;/binding&gt;
    &lt;/wsHttpBinding&gt;
  &lt;/bindings&gt;
  </code></pre>
  
  <p>The relevant service interface class looks so</p>
  
  <pre><code>namespace AssetManager.ServiceInterface
  {
  [ServiceContract]
  public interface IAssetServices
      { 
          [OperationContract]
          EmployeeDTO CreateNewEmployee(string firstName, string lastName);
      }
  }
  </code></pre>
  
  <p>The actual implementation looks like this</p>
  
  <pre><code>namespace AssetManager.ServiceInterface
  {
  public class AssetManagerServices : IAssetServices
  {
  
      #region IAssetServices Members
  
      [OperationBehavior(Impersonation = ImpersonationOption.Allowed)]
      public EmployeeDTO CreateNewEmployee(string firstName, string lastName)
      {
      }
   }
  }
  </code></pre>
  
  <p>I am using VS 2010, .net 4, IIS 7 (with following authentications enabled - Anonymous, ASP.NET impersonation, Basic Authentication, Digest Authentication and Windows Authentication). On the root web server in IIS, I clicked ISAPI and CGI Restrictions and allowed access to all extensions (asp.net 4.0 would probably be the relavent one)</p>
  
  <p>My current hurdle is that it says "Metadata publishing for this service is currently disabled" when I browse to the location in IE. This also doesn't let me add service references.</p>
  
  <p>As a final note, surely doing windows impersonation shouldn't be this difficult. What is the suggested way of doing impersonation for web services using WCF? In the asp.net world, it was as simple as adding    <code>&lt;authentication mode="Windows"/&gt;</code> and <code>&lt;identity impersonate="true"/&gt;</code></p>