views:

1236

answers:

4

My DBA requires all database access to be done through trusted domain account. This can be done if you set the web.config . This requires the user to login or to be on the domain for IE pass the credentials through. I want to impersonate a user by using code. I am using the code found in this knowledgebase article:

http://support.microsoft.com/kb/306158

It works great, I pass in the credentials, impersonate the user, then make the call to the database and data is returned.

The problem is if I go to another page, I lose my impersonated credentials. This means every time I make a call to the database I have to run the impersonate code.

If IIS can impersonate a domain user for all pages, then why can I not impersonate a user while using code?

It seems to be something with thread context switching. I have tried setting the alwaysFlowImpersonatingPolicy in the Aspnet.config file and it did not work.

http://msdn.microsoft.com/en-us/library/ms229553.aspx

Any suggestion? Is it even possible to do what I want?

A: 

Would this question help?

Jim Burger
+1  A: 

The reason you're losing the impersonation context is because each time a new page request ends the impersonation context will go out of scope.

As per the docs <alwaysFlowImpersonationPolicy> is used to ensure the same impersonation context is maintained across async calls. For example when making an async call to a remote web service the callback impersonation context is the same one as the initiating thread. In the case of ASP.NET the impersonation context would only flow for the lifetime of the page request.

Kev
+3  A: 

Impersonation occurs at the level of the thread. Impersonation causes the access token of the thread, which is usually inherited from the process, to be replaced with another. The best practice is to revert the effect of impersonation and thus the token as soon as you are done with the operation(s) for which it was needed. The story is no different with IIS or ASP.NET. Each request is usually handled by a distinct thread so you will have to make each thread impersonate the user.

This means every time I make a call to the database I have to run the impersonate code.

So that is correct.

If IIS can impersonate a domain user for all pages, then why can I not impersonate a user while using code?

IIS does not do it any differently and so it may only be a perceived illusion. It cannot impersonate a user for all pages unless all pages are being served by the same thread and where the impersonated token has never been reverted as each page is served.

It seems to be something with thread context switching.

Not really. Unless you are doing asynchronous processing (which you don't state you do in your question), the flow of the impersonation context won't be relevant. You only need to worry about flowing the impersonation context if you are causing a thread switch either directly or indirectly during the processing of a single request. If you want that the work done by a secondary (worker) thread continues to occur under the impersonation context of the primary one then you need to make sure the secondary thread borrows the impersonation token. In .NET Framework 1.1, you would have to take great care and manually orchestrate the flow of the impersonation context. With .NET 2.0, however, the ExecutionContext API was introduced and does a lot of the heavy-lifting.

Atif Aziz
A: 

You may find this example does the trick:

Imperatively Impersonate a User

It allows you to set a Username, Domain and Password and run with increased permissions and then revert back to standard permissions.

Lucifer