CodeSnip: Impersonation in ThreadPool Worker Threads
page 3 of 3
by J. Ambrose Little
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 36387/ 60

Summing It Up

If you've gotten this far, you've seen both how to share an impersonated identity with worker threads, and you've seen an example that demonstrates it works.  But in case you just skipped here or got lost in the midst of it all, here are the steps you need to take:

  1. Set up your application to run under a specific identity in IIS.
  2. Add the <identity impersonate="true" /> element to the system.web section of your Web.config (or Machine.config) file.
  3. Create a static/Shared member of type System.Security.Principal.WindowsIdentity.
  4. Set that shared member to be the identity of your main application threads.
  5. Do some asynchronous calling using ThreadPool.QueueUserWorkItem.
  6. In your worker thread method(s), create a new WindowsPrincipal using the shared identity from Step 3.
  7. Set the current thread's principal to that principal.
  8. Call Impersonate on the shared identity.
  9. Do your work using that identity.
  10. Call Undo on your impersonation context.

That's it.  In ten, relatively easy steps, you can ensure that all of your application's code is running under the same identity configured by you (or your hosting provider). 

In fact, to make your life easier, I've created a reusable class that you can plug into your application.  This class cuts out steps 3, 4, 6, and 7--nearly half.  All you need to do is download (includes C# and VB.NET version) the code and either drop the (language-appropriate) file into your project or copy and paste the class into your Global class.  If you do the latter, you can then simply call like below.

System.Security.Principal.WindowsImpersonationContext wi = Global.Impersonation.Impersonate();
// do some stuff
wi.Undo()

Again, calling Undo is optional, but it is recommended.  If you look at the class, it you will note that I get around step 4 (above) by creating a static property that will get the current thread's identity.  It is virtually guaranteed this will work as long as the first thread to call Impersonate is running under the desired identity, which should be the case most of the time.  If you want to be 100% sure, you can always still just set that property to the identity that you want prior to calling Impersonate.

Please note this article came out of a real need caused by just this situation with dasBlog and my hosting provider.  If you're curious, you can read about that on my blog.  Also note that I translated the impersonation helper class using Alex Lowe's translator.  It worked like a charm except it didn't understand my in-class #region statements.  It also didn't handle my delegate instantiation in my test code--I had to change it to use AddressOf Me.DoSomething, but it still saved me a lot of time!


View Entire Article

User Comments

Title: didn't work   
Name: Aisha
Date: 2009-07-21 12:35:25 PM
Comment:
Thanks for the tutorial.
I tried both way. First i did myself and second used your cs file. I didn't get any error about Impersonate() but my user didn't change it remain IUSR even after Impersonate() so i couldn't reach my file..
I use identity impersonate=true in my config file..
Using .net 2005 c#
Any idea?
Title: Director   
Name: H Malhotra
Date: 2006-08-17 4:52:50 PM
Comment:
Fixed our production issue.

Thanks
Title: Sweet   
Name: Matt
Date: 2006-08-09 12:55:07 PM
Comment:
Thanks for this. It's amazing how simple this code is but yet so complicated to find on the internet!
Title: The Answer To My Problem   
Name: Jeff
Date: 2006-05-25 11:13:47 AM
Comment:
This was the exact answer that I needed. It looks like .NET 2.0 offers us the HostingEnvironment class to work with, but our application isn't there yet.
Thanks!
Title: Problem inside a thread   
Name: Jack Freudenheim
Date: 2006-03-01 3:56:31 PM
Comment:
I can get your example to work perfectly when I do it from within an aspx page, but when I tried doing the impersonation from within a thread like this:

Thread thread = new Thread( new ThreadStart(myThread.Run));
thread.Start();

I get a security exception, "Unable to impersonate user".

Any ideas? I'm stuck and getting this to work would save me!
Title: Yer Welcome   
Name: J. Ambrose Little
Date: 2006-02-22 10:53:07 AM
Comment:
I'm glad I could help, Nois.
Title: Excellent.   
Name: Deepak
Date: 2006-02-16 10:01:06 AM
Comment:
Its really excellent article.I was really searching for this for 7-8 days but was not able to locate proper code.This article was really helpful and solved my acute problem.
Title: Good Idea   
Name: Ambrose
Date: 2005-03-23 1:30:36 PM
Comment:
Stefan,

Sounds like a great idea for an article (hint hint). Did you do any benchmarks to see how much running in separate contexts affected speed? I imagine it wouldn't be noticeable under most circumstances, and if it were asynchronous, it wouldn't matter at all really.
Title: Nice   
Name: Stefan
Date: 2005-03-23 12:57:31 PM
Comment:
Very nice. I did something similar with a RemoteProxy and a custom attribute, so you would have something like

[Impersonate]
private void DoSomething(object blah)
{
...
}

The proxy would then wrap the DoSomething call with the impersonation calls (Impersonate -> DoSomething -> Undo). Like this the app developer does not really need to know how to do the impersonation (simply tag the method that needs impersonation and you are done).

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2022 ASPAlliance.com  |  Page Processed at 2022-05-17 9:41:10 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search