WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation

We don't want to use AspNetCompatibility mode in case we ever want to take advantage of net.tcp or another custom binding, so is there a way to specify and implement impersonation (read: userName=,password=) on the WCF Service Host side? Did Microsoft in their infinite wisdom leave this out? 

I posed this question to my friend Dru today after we were having trouble finding a way to do it.  So there are plenty of articles on WCF Impersonation out there, but nearly all of them originate from the client side.  I want to originate my credentials from the service host side.  Why would you want to do that (you ask)? What if I don't want my client to pass me the credentials for my database (and I want to use windows authentication)?  The scenario is that we handle our application accounts at the domain level per environment. The username/password changes in every environment (Development/Test/QA/Production) so hardcoding the username/password in the service host source code is both bad design and no good (we don't even know what the passwords are in QA and Prod). 

Everywhere I look talks about how you most likely want to use compatibility for session state and/or that it is bad because it is less efficient and should only be used for migration purposes.

 

The Temporary (hopefully!) Solution

The only way we have found to do that so far is to turn on aspNetCompatibilityEnabled = “true” in the under system.serviceModel, add the identity to the system.web section in the config file, add your identity tag, and then add the AspNetCompatibilityRequirementsMode attribute to the top of the class.

 

Wenlong has a fantastic posting about Asp.Net Compatibility.

 

Web.config code:

<system.serviceModel>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
        <services>
            <service name="Organization.Services.TempService" behaviorConfiguration="wsServiceBehavior">
                <endpoint contract="Organization.Contracts.ITempServices"
                          binding="wsHttpBinding"
bindingConfiguration="TempService_wsHttpBinding"
name="TempServiceEndpoint" /> </service> </services> <behaviors> <serviceBehaviors > <behavior name="wsServiceBehavior" > <!-- Before deployment, you should remove the serviceDebug behavior to avoid disclosing information in exception messages --> <serviceDebug includeExceptionDetailInFaults="true" /> <serviceMetadata httpGetEnabled="true" /> <dataContractSerializer maxItemsInObjectGraph="100000" /> </behavior> </serviceBehaviors> </behaviors> <bindings> <wsHttpBinding> <binding name="TempService_wsHttpBinding" > <security mode="None" /> </binding> </wsHttpBinding> </bindings> </system.serviceModel> <system.web> <authorization> <allow users="?"/> </authorization> <identity impersonate="true" userName="me" password="you" /> <authentication mode="Windows"/> </system.web>

 

Service Implementation Class:

Imports Organization.Contracts
Imports System.Collections.Generic
Imports System.ServiceModel
Imports System.ServiceModel.Activation

<ServiceBehavior(), AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Required)> _
Public Class TempService : Implements ITempServices

...

End Class

 

 

You can set RequirementsMode to AspNetCompatibilityRequirementsMode.Allowed and it will still work fine.  The default is NotAllowed, which will cause errors.

Other References: http://msdn2.microsoft.com/en-us/library/aa702682.aspx

Update: I fixed an issue the endpoint not using the binding specified.

Print | posted @ Wednesday, October 3, 2007 1:29 AM

Comments on this entry:

Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by sacarro at 4/24/2008 2:38 PM

Doesn't hard coding <identity impersonate="true" userName="me" password="you" /> ignore your requirement of:

"The username/password changes in every environment (Development/Test/QA/Production) so hardcoding the username/password in the service host source code is both bad design and no good (we don't even know what the passwords are in QA and Prod). "?

I am running into a similar situation where we are running a wcf server as a service and it Identity is the machine rather than the user, so I am looking at how to impersonate after the processing is passed from the IIS server to the WCF service.
Find any good solutions?
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Fervent Coder at 4/24/2008 9:16 PM

Actually putting it in the configuration does not violate hard coded "magic" values. This gives us the opportunity to have it change in every environment. Have you looked at setting the service identity under the anonymous access account (Directory Security in IIS)? Another, much better option is to do a low level login for the elevated privileges just before you need to use the resource.
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Dips at 11/10/2008 4:07 AM

Re : <authentication mode="Windows"/>

right click on : WCFserviceProject -> properties ->UseIIswebService ->projectURL:"Create Virtual Directory For your Service here".By providing the path .
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Tim at 1/6/2009 7:03 PM

Hi.
I tried the above changes, but I've found that my wcf web service still executes under the NT AUTHORITY\NETWORK SERVICE Account.
Are you able to list the IIS Security setting you used?

Also does the Client (which calls the WS) security settings have any effect?

Thanks.

Tim.
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Robz at 1/6/2009 9:12 PM

@Tim: IIS settings are to anonymous I believe. You have to make sure you get all of the bold in the configuration and in the actual service code.
One of the settings in the configuration sets WCF to allow it to use ASP.NET compatibility, the second part impersonates an account.
Then in the code, you have set it able to use asp.net compatibility as well.
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Tim at 1/8/2009 10:40 PM

Thanks for the quick reply.

Yes - I've definitely got everything you've said. And it works locally out of Visual Studio.

One thing I didnt mention is that my WCF Web Service does a File Copy. This is what doesnt work on the deployed version.
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Tim at 1/18/2009 5:49 PM

Ok - some more info on this. As I said above, I've done all the things you said to do. And what I've found is:

1. Regardless of the impersonation identity, this ServiceSecurityContext.Current.PrimaryIdentity.Name ALWAYS = the NETWORK SERVICE Account. And its this Account that wcf uses to perform File IO and URL authorisation. This is the problem I have. I need to override this PrimaryIdentity Account, with the impersonation user.

2. I can get the impersonated user using this System.Security.Principal.WindowsIdentity.GetCurrent.Name. But this user is NOT used for File IO or URL authorisation.

Any thoughts? Am I barking up the wrong tree?

Tim.
Gravatar # re: WCF Impersonation - Specifying Windows Authentication Credentials on the Service Host Side of the WCF Equation
by Robz at 1/19/2009 9:49 AM

@Tim: Someone else recently ran into something very similar to this. He ended up using a Windows Service for the File Copy part.

You could play with WindowsImpersonationContext, but my friend wasn't able to get this to work correctly, possibly for the reasons you cited above.
Comments have been closed on this topic.