User Impersonation in WCF

Damir Dobric Posts

Next talks:

 

    

Follow me on Twitter: #ddobric



 

 

Archives

If there is one thing in software development which I don't really like, it is for sure something called "Trusted Delegation". I'm astonished how this "trouble making feature" is almost completely unknown in the world of software developers. I do not know what the reason is, but something's telling me, that it will make all (windows and none-windows) developers many, many troubles in the near future.

To understand what I'm talking about, just take a look on following very common scenario. Imagine you implement the system which consist of one WCF based client (C), one WCF based service (S). The client C invokes one operation O at the service S. The operation O has to open the file F and return some data from file to the client C.
To be honest, this example is a little more advanced Hello World.

Unfortunately, this "Hello World" example is much complicated than most developers would expect. If you ask one architect about this example he will probably ask some additional question like:

  1. "What is the user security account running the client C"?
  2. "What is the user security account running the service S?"
  3. Who is permitted to access the file F?
  4. Last but not least: "Does the service need to impersonate the user account running on the client?"
  5. Is there a scenario which requires that the users' account from the client has to be delegated

Without of answering ALL of these questions, you will NEVER be able to deploy such service to your customer. Why?
When the client C and the services, for the sake of simplicity, are both running on the same machine and the file F is stored on some other machine, all will work fine. The only requirement to make it working is to use proper binding and to set the Endpoint Identity like shown in following example:

  <endpoint address="" 
            binding="wsHttpBinding
            contract="Microsoft.ServiceModel.Samples.IMyService" > 
     <identity> 
          <userPrincipalName value="svcuseraccount@DOMAIN " /> 
      </identity> 
  </endpoint>

The user principal name is the name of the user account of the service: DOMAIN\svcuseraccount. The same identity has to be set on the service and on all clients. This is the ability of WCF to prevent phishing attacks.

The service operation AccessFile looks like:

        public void AccessFile() 
        { 
            TryFileAccess(); 
        }     

        private static void TryFileAccess() 
        {
            try 
            { 
                File.OpenRead(@\\REMOTEHOST\testpermit.txt); 
                Console.WriteLine("ok"); 
            } 
            catch (Exception ex) 
            { 
                Console.WriteLine("deny"); 
            }

         }


The client would invoke the operation as shown below:

CalculatorProxy proxy = new CalculatorProxy();
proxy.AccessFile();

When the service tries to open the file the user who is opening the file is the service user. In this case DOMAIN\svcuseraccount. If this user has the access permission to the file, the file will be opened. If the client is started on the same machine as service (which is an EXE) client's and service's users are same: DOMAIN\svcuseraccount. If you start now the client in context of some other user i.e.: DOMAIN\clientuser, the service will still access the file as DOMAIN\svcuseraccount.

Now, what if the requirement is that he file should be accessed on behalf of the user who is running the client? That means, that the code in operation AccessFile should run as it would be invoked by user DOMAIN\clientuser. This is in many enterprises very common scenario.

To do that following changes have to be performed. Set the impersonation at the operation in the service

[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public double Add(double n1, double n2)

and request the kind of impersonation at the client side:

proxy.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
CalculatorProxy proxy = new CalculatorProxy();
proxy.AccessFile();

When you now starts the client with "runas" as user DOMAIN\clientuser the service will in the operation impersonate the user as it would be DOMAIN\clientuser and not the service account DOMAIN\svcuseraccount. Now, the file will be opened if the DOMAIN\clientuser has a permission to open the file independent of the permission of service user DOMAIN\svcuseraccount.

Following code can be used to display various user identities:

        static void DisplayIdentityInformation() 
        {
            Console.WriteLine("\t\tWindows Identity            :{0}", WindowsIdentity.GetCurrent().Name); 
            Console.WriteLine("\t\tThread Impersonation level :{0}", WindowsIdentity.GetCurrent().ImpersonationLevel); 
            Console.WriteLine("\t\thToken                    :{0}", WindowsIdentity.GetCurrent().Token.ToString()); 
            Console.WriteLine("\t\tThread Identity            :{0}", Thread.CurrentPrincipal.Identity.Name); 
        }

In this post I showed how to impersonate the client's user account in the service. Describes solution is very simple. Unfortunately thing get complicated whet the client C, service S and the file F are all on different machines. In this example we used the TokenImpersonationLevel impersonate. This level is used when the resources accessed from the service are on the same machine as service. If the service has to access the resource (in this case file F), which is on some other machine then the TokenImpersonationLevel delegate has to be used. In my next post I will describe how to do that.


Posted Oct 14 2007, 12:01 AM by Damir Dobric
Filed under:

Comments

Yaron wrote re: User Impersonation in WCF
on 10-19-2007 18:16

Interesting post. I have a question: I want to run my client as user A with "run as" , but I want my proxy calls to impersonate user B whose user/pass I know. How can I do this?

Damir Dobric wrote re: User Impersonation in WCF
on 10-20-2007 0:03
Impersonating by username and password - Damir Dobric Posts wrote Impersonating by username and password - Damir Dobric Posts
on 10-20-2007 0:05

Pingback from  Impersonating by username and password - Damir Dobric Posts

Yaron wrote re: User Impersonation in WCF
on 10-20-2007 0:30

Thanks a lot

Keyse wrote re: User Impersonation in WCF
on 04-11-2008 17:51

Please also do not forget that client may not be WCF based and will NOT be able to make calls like:

proxy.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

Rajalakshmi wrote re: User Impersonation in WCF
on 12-30-2008 12:27

Hi Damir, could you please post an example for TokenImpersonationLevel delegate too?

Mac73 wrote re: User Impersonation in WCF
on 04-01-2009 3:45

Do you have article for this?

Unfortunately thing get complicated whet the client C, service S and the file F are all on different machines.

My client is window service, WCF is hosted in IIS on different account. File Server is different machine and i do have domain account to access files.

Damir Dobric wrote re: User Impersonation in WCF
on 04-01-2009 9:08

Hi Mac,

There is one example in WCF samples. Just search for TokenImpersonationLevel .

Damir Dobric wrote re: User Impersonation in WCF
on 04-07-2009 17:30

Here is a very good MSDN article which describes this topic in more details:

msdn.microsoft.com/.../ms730088.aspx

Damir Dobric Posts wrote Impersonation and Reverting of Identity
on 05-15-2009 23:59

When working with server based applications like ASP.NET and WCF or other services, you will for sure

DamirDobric wrote Impersonation and Reverting of Identity
on 05-16-2009 0:45

When working with server based applications like ASP.NET and WCF or other services, you will for sure

Damir Dobric Posts wrote Using of Impersonation with DataServices
on 12-23-2009 1:00

When working with web services and ADO.NET services (O-data) you will sometimes have requirement to invoke

DamirDobric wrote Using of Impersonation with DataServices
on 12-23-2009 1:14

When working with web services and ADO.NET services (O-data) you will sometimes have requirement to invoke

Rampid Byter wrote WCF 403.1 Error Page
on 06-05-2010 3:32

WCF 403.1 Error Page

Marie wrote re: User Impersonation in WCF
on 01-03-2011 11:59

Nice post! I wish it came with a variation of sample solutions...

What if I want only the server code to access the file residing in the same server as the service and not one else

To answer your questions.

1) should I care?  (see 3)

2) I am no sure.   I am putting this wcf1.svc code on a godaddy shared hosting, (some posts say use the ftp account ?user/pass?)

is there a way to display the current credentials on the server that are failing on this clienbin\data\some.xml folder?

3) I want only the server code to have access r/w

4) & 5) no

What do I need to put in my web.config? is the ServiceReference.ClientConfig impacted in this?

Does your article "Impersonating by username and password" apply to my wcf1.svc.cs code ?

Thanks

Marie wrote re: User Impersonation in WCF
on 01-03-2011 12:01

Nice Post! I only wish it came with some variations of sample code

solutions....

What if I want only the server code to access the file residing in the same server as the service and not one else

To answer your questions.

1) should I care?  (see 3)

2) I am no sure.   I am putting this wcf1.svc code on a godaddy shared hosting, (some posts say use the ftp account ?user/pass?)

is there a way to display the current credentials on the server that are failing on this clienbin\data\some.xml folder?

3) I want only the server code to have access r/w

4) & 5) no

What do I need to put in my web.config? is the ServiceReference.ClientConfig impacted in this?

Does your article "Impersonating by username and password" apply to my wcf1.svc.cs code ?

Thanks

mike wrote re: User Impersonation in WCF
on 08-15-2011 18:31

No N-tier service uses delegation of end-user credentials.  It is not scalable, and it is not secure to establish privileges for a user account on server resources.

Batoul wrote re: User Impersonation in WCF
on 02-18-2012 4:37

I am using a Mac Citrix ICA Client to cmtaunicome with a PC running windows. While connected to the PC, when I hold the shift key, the next letter after the intended one gets Capitalized. This begins right at the login window for Windows XP 64. How can I resolve this?

developers.de is a .Net Community Blog powered by daenet GmbH.