3

Given that I have a WCF service using windows authentication, and I want to impersonate them and call another WCF service, like so:

using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{
    // call another WCF service
}

I've set all the config settings and it works fine, as long as on the client side,they include the following line:

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Delegation;

But, how do I verify before trying to make the call that the user token has delegation rights? i.e. the client, which I don't control, has set the AllowedPersonationLevel?

If they haven't set it, all sorts of weird exceptions get thrown (like cannot load assembly X etc).

Ideally, I'd like to be able to do the following:

using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())
{
    if (UserDoesntHaveDelegationRights())
        throw new SecurityException("No delegation rights");

    // call another WCF service
}

Note that WindowsIdentity.GetCurrent().ImpersonationLevel is always equal to TokenImpersonationLevel.Impersonation, so that unfortunately is not an option.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Gareth
  • 2,424
  • 5
  • 26
  • 44

2 Answers2

6

There might be some confusion here in definitions. In terms of impersonation levels a windows identity can be:

  • Impersonated - the service can impersonate the user locally
  • Delegated - the service can impersonate the user remotely

The ability to delegate is so powerful that its highly restricted in Active Directory:

  1. The Client has to allow delegation
  2. The service account which is doing the delegation must be marked as "trusted for delegation" in Active Directory.

Here's how to enable an account for delegation. It requires a Active Directory domain admin to the make the change. Every corporate environment that I've ever worked in has a policy that does not allow Delegation.

Back to your question:

So while TokenImpersonationLevel.Delegation exists, its considered a security risk and rarely (if ever) used. TokenImpersonationLevel.Impersonation is the highest level that you will probably ever get.

TokenImpersonationLevel.Impersonation is useful. You can still connect to a database or make a remote service call as the impersonated user. But a remote service (not on the same box) can't impersonate the user a second time. The basic rule of thumb is "impersonation enables two machines hops". If the user's credentials have to "hop" farther, it will fail.

If you need to pass a user's credentials between many servers the best choice is a federated security model such as Windows Identity Foundation (WIF). See Identity Management in Active Directory.

ErnieL
  • 5,773
  • 1
  • 23
  • 27
0

What about

if (WindowsIdentity.GetCurrent().ImpersonationLevel != TokenImpersonationLevel.Delegation) ...
Slava
  • 1,065
  • 5
  • 11
  • Yea, that is what I thought - but WindowsIdentity.GetCurrent().ImpersonationLevel is always equal to Impersonation – Gareth Mar 14 '13 at 05:12