问题
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.
回答1:
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:
- The Client has to allow delegation
- 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.
回答2:
What about
if (WindowsIdentity.GetCurrent().ImpersonationLevel != TokenImpersonationLevel.Delegation) ...
来源:https://stackoverflow.com/questions/15380054/verify-that-the-currently-authenticated-windows-user-has-delegation-rights