Search code examples
wcfauthenticationwcf-securityimpersonation

How to require impersonation on a WCF service and set credentials from within the service?


I have a WCF service in which I am trying to set up a set of credentials so that they will be used not only for the service, but also for all subsequent operations on the NAS.

I currently have set the attribute [OperationBehavior(Impersonation = ImpersonationOption.Required)] on the method and have set <identity impersonate="true" userName="DOMAINUSER" password="PASSWORD"/> within the service web.config. Since this is an internal service and I don't want to require special credentials from the consumer I would like to use <basicHttpBinding> with <security mode="None">. The issue is that when set this way I receive the error:

The contract operation requires Windows identity for automatic impersonation. 
A Windows identity that represents the caller is not provided by
binding 'BasicHttpBinding' for contract.

Set as above, the WindowsIdentity.GetCurrent().Name returned is NT AUTHORITY\NETWORK SERVICE despite having the impersonation directive set in the web.config. It seems to want the credentials passed from the consumer/client rather than set from within the service.

Is it possible to have the impersonation contained completely within the service rather than relying upon the consumer to send the credentials?

Thanks!


Solution

  • Yes it is possible but it is not done through any configuration. What you used so far is WCF impersonation which targets only impersonation of client's identity.

    What you want is using different accounts (probably based on some logic) for accessing remote storage. First of all it is not very secure way because it requires to store accounts and passwords used to access those resources in some configuration file or registry (or even worse - hard code them). You should run your service with special account created just for your application and this account should have necessary permissions for every resource you need.

    Anyway you need to log in your specific account and impersonate it. As I know .NET doesn't have API for log in - you must use interop and call Win API LogonUser method.