Parallel.ForEach () меняет контекст олицетворения
Сегодня мы развернули наше недавно созданное приложение 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 не проверяет контекст, прежде чем передать его в ОС.
Есть идеи, почему это происходит? Это известная проблема / ошибка?