Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set the user identity for tasks when calling Task.WaitAll()?

I'm having a problem invoking WCF services in parallel. I'm trying to use Tasks to invoke two services in parallel to save some time (I'm NOT trying to make this async), but my tasks are being run as another user. Both services require Windows authentication and both calls fail because the user invoking the service does not have the required permissions.

The calling code (code below) is located inside a Controller Action in ASP.NET MVC4, running IIS 7.5. All application pools involved are set to allow ASP.NET Impersonation and require Windows Authentication (all other methods set to disabled).

// Parallel service request to two services
Task<object>[] tasks = new Task<object>[2];

// this shows my credentials, e.g. "MYDOMAIN\\MyUsername"
var userMe = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

tasks[0] = Task<object>.Factory.StartNew(() => 
{
    // this shows "IIS APPPOOL\\DefaultAppPool"
    var user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

    var data = client1.MyMethod();
    return data;
});

tasks[1] = Task<object>.Factory.StartNew(() =>
{
    // this shows "IIS APPPOOL\\DefaultAppPool"
    var user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

    var data = client2.MyMethod();
    return data;
});

Task.WaitAll(tasks);

My problem: How do I instruct the tasks to run as the current user, instead of running as the "IIS APPPOOL\DefaultAppPool" user?

like image 693
Valdemar Avatar asked Apr 22 '13 14:04

Valdemar


Video Answer


2 Answers

Try this:

WindowsIdentity impersonatedUser = WindowsIdentity.GetCurrent();

Task<object>.Factory.StartNew(() =>
{
    using (WindowsImpersonationContext ctx = impersonatedUser.Impersonate())
    {
       //Your code
    }
    return data;
});
like image 89
Vyacheslav Volkov Avatar answered Sep 18 '22 17:09

Vyacheslav Volkov


You might want to look into whether setting <alwaysFlowImpersonationContext> is appropriate:

Specifies that the Windows identity always flows across asynchronous points, regardless of how impersonation was performed.

By default, this setting is off within ASP.Net, and so the tasks (running, potentially, on other threads) end up just running with no impersonation in place.

Otherwise (if it's not appropriate to set that), I think you could capture the WindowsIdentity object into a local variable that's captured by the Tasks, and then call Impersonate() on it from within the task. (although I haven't tried this)

like image 40
Damien_The_Unbeliever Avatar answered Sep 20 '22 17:09

Damien_The_Unbeliever