如何在调用Task.WaitAll()时设置任务的用户标识?

本文关键字:设置 任务 用户标识 调用 Task WaitAll | 更新日期: 2023-09-27 18:10:16

我在并行调用WCF服务时遇到问题。我试图使用任务并行调用两个服务以节省一些时间(我不是试图使此异步),但我的任务正在作为另一个用户运行。两个服务都需要Windows身份验证,两个调用都失败,因为调用服务的用户没有所需的权限。

调用代码(下面的代码)位于ASP中的Controller Action中。NET MVC4,运行IIS 7.5。所有涉及的应用程序池都设置为允许ASP。. NET模拟和要求Windows身份验证(所有其他方法设置为禁用)。

// 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);

我的问题:我如何指示任务以当前用户运行,而不是以"IIS APPPOOL'DefaultAppPool"用户运行?

如何在调用Task.WaitAll()时设置任务的用户标识?

试试这个:

WindowsIdentity impersonatedUser = WindowsIdentity.GetCurrent();
Task<object>.Factory.StartNew(() =>
{
    using (WindowsImpersonationContext ctx = impersonatedUser.Impersonate())
    {
       //Your code
    }
    return data;
});

您可能需要查看设置<alwaysFlowImpersonationContext>是否合适:

指定Windows标识始终跨异步点流动,而不管模拟是如何执行的。

默认情况下,此设置在ASP中是关闭的。因此,任务(可能在其他线程上运行)最终只是运行,没有适当的模拟。

否则(如果不适合设置),我认为您可以将WindowsIdentity对象捕获到由Task s捕获的局部变量中,然后从任务内调用Impersonate()。(虽然我还没有尝试过)