JG Vimalan's Blog

Sharing is caring :)

Using Windows Identity and Impersonation with WCF on IIS 7



There are times when the identity of the caller is required within the services for various actions.  One example is to capture the username of the caller to write to an audit field in the database to track changes by user.
When calling .asmx based services the Client credentials were added to the proxy before the call was made.  With WCF the identity of the caller can be passed to the services using configuration settings.

Service Code

    [ServiceContract]
    public interface IIdentService
    {
        [OperationContract]
        string TestIdentity();
    }

    public class IdentService : IIdentService
    {
        public string TestIdentity()
        {
            IPrincipal principal = Thread.CurrentPrincipal;

            return string.Format(“The identity that the service is running under is {0}”, principal.Identity.Name);
        }
    }

Service Configuration

  <configuration>   
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name=”NewBinding0″>
          <security mode=”TransportCredentialOnly”>
            <transport clientCredentialType=”Windows”/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service name=”WcfServiceIdentitySample.IdentService”>
        <endpoint address=”http://localhost/WcfIdentService/Service1.svc
                  binding=”basicHttpBinding”
                  bindingConfiguration=”NewBinding0″
                  contract=”WcfServiceIdentitySample.IIdentService” />
      </service>
    </services>
  </system.serviceModel>
 <system.webServer>
   <validation validateIntegratedModeConfiguration =”false”/>
    <modules runAllManagedModulesForAllRequests=”true” />
  </system.webServer>
    <system.web>
        <identity impersonate=”true” />
    </system.web>
</configuration>

The interesting points are:
– In system.servicemodel/bindings/basicHttpBinding/binding  the security is configured to require Windows credentials to be supplied.
– In system.webServer validation is set to false for the Integrated pipeline mode.  The new IIS model does not allow impersonated identity at all stages in the process and will throw an error unless validation is turned off
– system.web identity is set to impersonate on the thread
– basicHttpBinding must be used rather than wsHttpBinding as wsHttpBinding is incompatible with Windows Authentication

Client Code

        protected void Page_Load(object sender, EventArgs e)
        {
            MyService.IdentServiceClient proxy = new MyService.IdentServiceClient();

            string result = proxy.TestIdentity();

            Response.Write(result);
        }

Client Configuration

<system.web>
    <compilation debug=”true” targetFramework=”4.0″ />

    <authentication mode=”Windows”/>
    <identity impersonate=”true”/>

  </system.web>

  <system.webServer>

    <validation validateIntegratedModeConfiguration =”false”/>
     <modules runAllManagedModulesForAllRequests=”true” />
  </system.webServer>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name=”BasicHttpBinding_IIdentService” closeTimeout=”00:01:00″
            openTimeout=”00:01:00″ receiveTimeout=”00:10:00″ sendTimeout=”00:01:00″
            allowCookies=”false” bypassProxyOnLocal=”false” hostNameComparisonMode=”StrongWildcard”
            maxBufferSize=”65536″ maxBufferPoolSize=”524288″ maxReceivedMessageSize=”65536″
            messageEncoding=”Text” textEncoding=”utf-8″ transferMode=”Buffered”
            useDefaultWebProxy=”true”>
          <readerQuotas maxDepth=”32″ maxStringContentLength=”8192″ maxArrayLength=”16384″
              maxBytesPerRead=”4096″ maxNameTableCharCount=”16384″ />
          <security mode=”TransportCredentialOnly”>
            <transport clientCredentialType=”Windows” proxyCredentialType=”None”
                realm=”” />
            <message clientCredentialType=”UserName” algorithmSuite=”Default” />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address=”http://localhost/WcfIdentService/Service1.svc
          binding=”basicHttpBinding” bindingConfiguration=”BasicHttpBinding_IIdentService”
          contract=”MyService.IIdentService” name=”BasicHttpBinding_IIdentService” />
    </client>
  </system.serviceModel>

The interesting points are:
– system.web authentication and identity values need to be set.
– system.webserver validation must be turned off as noted for the services. 
– System.serviceModel/bindings/basicHttpBinding/security this matches the configuration on the server
IIS Configuration
The web application was configured with Windows Authentication and ASP.NET Authentication using a .NET 4.0 Integrated pipeline.

October 14, 2010 - Posted by | WCF

3 Comments »

  1. I like your blog. keep blogging.

    Comment by Cool | November 24, 2010 | Reply

  2. Thanks for sharing!

    Comment by Chris | December 28, 2010 | Reply

  3. […] I have looked online for the answers but thus far the best i have found is this: https://jgvimalan.wordpress.com/2010/10/14/using-windows-identity-and-impersonation-with-wcf-on-iis-7&#8230; […]

    Pingback by Not passing Credentials to WCF Service resulting in a 401 | BlogoSfera | October 2, 2013 | Reply


Leave a comment