【发布时间】:2014-11-21 19:04:58
【问题描述】:
今天我们将新创建的 ASP.NET 应用程序部署到服务器上,很快我们就意识到有一个奇怪的安全相关问题导致应用程序崩溃。这是一个内部应用程序,我们使用模拟来管理用户访问资源的方式。但是,当用户尝试访问他们可以完全控制的文件夹时,应用程序会引发“拒绝访问”异常。
该异常实际上是一个AggregateException,并被抛出在一个使用Parallel.ForEach 枚举列表和正文内部的方法中,它尝试访问该文件夹,但此时模拟上下文已更改并且工作线程作为应用程序池的身份运行,它无权访问该文件夹,因此出现异常。
为了确认这一点,我查看了Parallel.ForEach 正文之前和内部的进程标识:
string before = WindowsIdentity.GetCurrent().Name;
Debug.WriteLine("Before Loop: {0}", before);
Parallel.ForEach(myList, currentItem =>
{
string inside = WindowsIdentity.GetCurrent().Name;
Debug.WriteLine("Inside Loop: {0} (Worker Thread {1})", inside, Thread.CurrentThread.ManagedThreadId);
});
当我运行应用程序时,会打印出以下内容:
Before Loop: MyDomain\ImpersonatedUser
Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 8)
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 6)
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7)
Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 9)
Inside Loop: NT AUTHORITY\SYSTEM (Worker Thread 10)
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7)
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 6)
Inside Loop: MyDomain\ImpersonatedUser (Worker Thread 7)
如您所见,一些线程作为模拟身份运行,一些作为应用程序池运行(在本例中为LocalSystem),似乎没有模式。 Call Stack 窗口中的前一帧也转到非托管 kernel32.dll,这让我认为 CLR 在将上下文委托给操作系统之前没有对其进行验证。
知道为什么会这样吗?这是一个已知问题/错误吗?
【问题讨论】:
标签: c# .net task-parallel-library impersonation parallel.foreach