Know Your Impersonation Methods

- J.D. Meier, Carlos Farre, Jason Taylor, Prashant Bansode, Steve Gregersen, Madhu Sundararajan, Rob Boucher

Impersonation is used to restrict or authorize original caller’s access to a WCF service’s local resources, like files etc. There are three options for impersonation:
  • Impersonating the original caller declaratively on specific operations.
  • Impersonating the original caller declaratively on the entire service.
  • Impersonating the original caller programmatically within an operation.

Impersonating the original caller declaratively on specific operations

Use this option when you want to impersonate the original caller for entire duration of specific operation. Impersonation is a costly operation and is usually used for higher privileged original callers, hence using impersonation selectively only on the operations which need it reduces the potential attack surface. You can impersonate declaratively by applying the OperationBehaviorAttribute attribute on any operation that requires client impersonation, as shown in the following code example.
[*OperationBehavior*(Impersonation = ImpersonationOption.*Required*)]
public string GetData(int value)
{
   return “test”;
}

Impersonating the original caller declaratively on the entire service

Use this option when you want to impersonate the original caller for entire duration of all the operations. Impersonation is a costly operation and is usually used for higher privileged original callers. You need to be careful when opting for this as it potentially increases the attack surface. For impersonating the entire service set the impersonateCallerForAllOperations attribute to "true" in the WCF configuration file, as shown in the following example.
...
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
      <serviceAuthorization *impersonateCallerForAllOperations="true"* />
    </behavior>
  </serviceBehaviors>
</behaviors>
...

When impersonating for all operations, the Impersonation property of the OperationBehaviorAttribute applied to each method must also be set to either Allowed or Required.

Note: When a service has higher credentials than the remote client, the credentials of the service are used if the Impersonation property is set to Allowed. That is, if a low-privileged user provides its credentials, a higher-privileged service executes the method with the credentials of the service, and can use resources that the low-privileged user would otherwise not be able to use.

Impersonating the original caller programmatically within an operation

Use this option when you want to impersonate the original caller for a small duration in a service operation. Impersonation is costly operation and is usually used for higher privileged original callers, hence using impersonation only when its needed reduces the potential attack surface. Perform programmatic impersonation as shown in the following example.
public string GetData(int value)
{	
 using (*ServiceSecurityContext*.Current.WindowsIdentity.*Impersonate*())
 {
     // return the impersonated user (original users identity)
     return string.Format("Hi, {0}, you have entered: {1}",
          WindowsIdentity.GetCurrent().Name, value);
 }   
}

Note: It is important to revert to impersonation. Failure to do so can form the basis for denial of service and elevation of privilege attacks. In the example above the using statement ensures that the impersonation is reverted after execution of the using block.

Additional Resources

Last edited Jun 12, 2008 at 9:38 PM by prashantbansode, version 1

Comments

No comments yet.