WCF: How to Allow Impersonation for Operations

17. April 2007 00:43

I recently received a question from someone having some trouble with impersonation:

"When I set the attribute impersonateCallerForAllOperations="true" in the web.config files, I obtain an InvalidOperationException saying that the operation does not allow impersonation."

Fortunately, this is an easy problem to solve. 

There are three impersonation options for operations in WCF that are encapsulated by the enumeration System.ServiceModel.ImpersonationOption:

  1. Allowed - Impersonation is supported when credentials are available and ImpersonateCallerForAllOperations is set to true.

  2. Not Allowed - Impersonation is not supported and an exception will occur if ImpersonateCallerForAllOperations is set to true.

  3. Required - Impersonation is required.  It is not optional and an exception will occur if the credentials are not available or ImpersonateCallerForAllOperations is set to false.

By default, WCF applies Not Allowed as the impersonation option for a given operation.  In order to enable impersonation, it is necessary to specify Required or Allowed via an OperationBehavior as shown below:

[OperationBehavior(Impersonation = ImpersonationOption.Allowed)]

If you separate your contract and implementation (and I hope you do), keep in mind the OperationBehavior cannot be applied to the contract.  It has to be applied to the implementation.  Rather than placing it on the appropriate method in your interface, it would be placed on the appropriate method in the class that implements the interface.  In other words, it goes with your service implementation rather than your service contract.

It is also necessary to set the ImpersonateCallerForAllOperations property to true in the Service Authorization Behavior.  The easiest way to accomplish this is by creating a behavior in your configuration file and referencing it from your service.  An example is shown below:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyBehavior">
          <serviceAuthorization impersonateCallerForAllOperations="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyBehavior" name="MyService">
        <endpoint 
          address="service" 
          binding="wsHttpBinding" 
          name="MyHttpBinding"
          contract="MyServiceContract" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/myService/" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

This should get your impersonation up and running.

Comments are closed

About Me

I'm a passionate software developer and advocate of the Microsoft .NET platform.  In my opinion, software development is a craft that necessitates a conscious effort to continually improve your skills rather than falling into the trap of complacency.  I was also awarded as a Microsoft MVP in Connected Systems in 2008, 2009, and 2010.


Can’t code withoutThe best C# & VB.NET refactoring plugin for Visual Studio
Follow jeff_barnes on Twitter

View Jeff Barnes's profile on LinkedIn

 

Shared Items

Disclaimer

Anything you read or see on this site is solely based on my own thoughts.  The material on this site does not necessarily reflect the views of my employer or anyone else.  In other words, I don't speak for anyone other than myself.  So, don't assume I am the official spokesperson for anyone.