Parallel.ForEach () altera o contexto de representação
Hoje, implantamos nosso aplicativo ASP.NET recém-criado no servidor e logo percebemos que havia um problema estranho relacionado à segurança que estava causando a falha do aplicativo. Esta é uma aplicação interna e usamos a representação para gerenciar como os usuários acessam recursos. O aplicativo, no entanto, lança uma exceção "Acesso negado" quando o usuário tenta acessar uma pasta sobre a qual ele tem controle total.
A exceção foi de fato umaAggregateException
e estava sendo lançado em um método que usaParallel.ForEach
para enumerar em uma lista e dentro do corpo, ele tenta acessar a pasta, mas neste momento o Contexto de Representação é alterado e o segmento de trabalho é executado como a identidade do pool de aplicativos, que não tem acesso à pasta, daí a exceção.
Para confirmar isso, observei a identidade do processo antes e dentro do corpo doParallel.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);
});
Quando executo o aplicativo, é isso que é impresso:
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)
Como você pode ver, alguns threads estão sendo executados como a identidade representada e outros como o pool de aplicativos (nesse caso,LocalSystem
) e não parece haver um padrão. O quadro anterior noCall Stack
janela também vai para o não gerenciadokernel32.dll
, o que me faz pensar que o CLR não está validando o contexto antes de delegá-lo ao sistema operacional.
Alguma idéia de por que isso está acontecendo? Esse é um problema / bug conhecido?