Question

So I am working on setting up a WCF service, hosted in iis7. The service is a REST service.

Up till now our requirements for authentication were that only domain accounts were going to connect to the service. We are using basic authentication and using impersonation for making calls through our business layer to our DB.

This is all working well.

Now we have the need to allow non-domain accounts to use our service. Due to somethings with IIS I implemented this (http://custombasicauth.codeplex.com/) and a custom membership provider that will (depending on the username passed in) either attempt to Auth against Active Directory, or against a asp.net membership provider. This part is working correctly.

The issue now that I have is that impersonation is not working (which is understandable.) Now, this is where I am lost and need help with direction or clearing of all the fog. What I want to do (and I don't know if this is possible) is this:

IF a user is a domain user THEN impersonate their account. IF NOT a domain user THEN impersonate the "generic user domain account". As a bonus I would like to this to happen "behind the scene" so that each method we have doesn't need special logic added to handle this.

I have read a bunch of stuff about identities, policy providers, role providers...and now I am thoroughly confused.

Anyone have some insight into this?

Was it helpful?

Solution

So after a lot of looking online for more information on impersonation works with IIS, I couldn't find much helpful info. So I began to look more into "hacking" it in.

I was using this (http://custombasicauth.codeplex.com/) to allow us to have custom basic authentication with WCF.

how this module flows is LeastPrivilege.CustomBasicAuthentication.CustomBasicAuthenticationModule.OnEnter()
is called when a connection is established. This in turn calls LeastPrivilege.CustomBasicAuthentication.CustomBasicAuthenticationModule.AuthenticateUser() which, eventually calls LeastPrivilege.CustomBasicAuthentication.CustomBasicAuthenticationModule.SetPrincipal(string username)

I changed SetPrincipal to accept a password also private static void SetPrincipal(string username, string password)

In here I do a simple if on the username (checking for a our domain prefix) to determine if the user is a domain account or not. If it is a domain account I use their username/password to create a WindowsIdentity (I used http://www.codeproject.com/KB/dotnet/UserImpersonationInNET.aspx with a little refactoring to get just the WindowsIdentity). If the user wasn't a domain account I use a known hardcoded domain account for them. I then take this WindowsIdentity and create a WindowsPrincipal and I set that to HttpContext.Current.User

So this works for us. Impersonation is working. As a side effect of this we don't need to decorate our WCF methods with the [OperationBehavior(Impersonation = ImpersonationOption.Required)] attribute. I don't know if this is the "Correct" way of doing it, but I think it is pretty close. I think IIS detects that there is a WindowsPrincipal in Current User and automatically impersonates that account.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top