Use QueueBackgroundWorkItem with User Identity?
Asked Answered
I

2

9

I am using HostingEnvironment.QueueBackgroundWorkItem to run work in the background of an ASP.Net application, based on Scott Hanselman's blog post How to run Background Tasks in ASP.NET.

I'd like to run the background task as the current user's identity. I have tried passing a WindowsPrincipal and setting Thread.CurrentPrincipal in the action, but this didn't result in the Action executing as the current user.

Is this possible, or does using HostingEnvironment always imply running as the App pool identity?

Edit

Not exactly on point to my original question, but I also tried to pass a value via CallContext.LogicalSetData() and CallContext.LogicalGetData(). On the Get side, the value is always null.

Edit #2

Also tried this on the queuing side:

using (HostingEnvironment.Impersonate(windowsIdentity.Token))
{
     HostingEnvironment.QueueBackgroundWorkItem(work);
}

When the work is actually done, the current WindowsIdentity in the Action is still the app pool identity.

Ithaman answered 29/6, 2015 at 21:34 Comment(1)
The docs say "This overloaded method doesn’t flow the ExecutionContext or SecurityContext from the caller to the callee. Therefore, members of those objects, such as the CurrentPrincipal property, will not flow from the caller to the callee." msdn.microsoft.com/en-us/library/…Thorwald
S
1

any specific reason why you "must" use "HostingEnvironment" ?

or Have you tried to use the WindowsImpersonationContext ?

System.Security.Principal.WindowsImpersonationContext impersonationContext;
impersonationContext = 
    ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();

//Insert your code that runs under the security context of the authenticating user here.

impersonationContext.Undo();

you can find out more how to do it here

Subsidy answered 2/7, 2015 at 23:7 Comment(1)
See the explanation of what it does in the link in the question. It has to be scheduled as it is to (help) prevent the threads being killed if the AppDomain tries to shut down.Ithaman
E
0

The current user's identity is attached to the thread handling the request, and is only valid for the lifetime of that request. Even if you passed a reference to HttpContext.Current.User.Identity to your worker function, you would find that it may no longer be valid when you try to use it. As far as I can tell, you need to do a bit of work with the Windows API to clone the identity token to make a new WindowsIdentity, which you can then use in your background task. So something like this:

IntPtr copy = IntPtr.Zero,
    token = ((WindowsIdentity)HttpContext.Current.User.Identity).Token;
if (DuplicateToken(token, ref copy))  // the WinAPI function has more parameters, this is a hypothetical wrapper
{
    return new WindowsIdentity(copy);
}
// handle failure

Pass this WindowsIdentity to your background task, and impersonate it when you need to. Don't forget to dispose of it.

Eradis answered 10/11, 2015 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.