今天,我們將新創建的ASP.NET應用程序部署到服務器,很快我們意識到存在一個奇怪的安全相關問題,導致應用程序崩潰。這是一個內部應用程序,我們使用模擬來管理用戶訪問資源的方式。但是,應用程序在用戶試圖訪問完全控制的文件夾時會拋出「拒絕訪問」異常。Parallel.ForEach()更改模擬上下文
唯一的例外是實際上是一個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在將其委託給操作系統之前未驗證上下文。
任何想法爲什麼會發生這種情況?這是一個已知的問題/錯誤?
但爲什麼它確實似乎不是一種模式? – abatishchev 2014-09-26 17:53:23
我不太確定。我以前見過有關這種方式的問題。看起來像*應該*被實現的特徵,因爲它是*期望*行爲。 – 2014-09-26 18:00:37
是的,我使用'WindowsIdentity.GetCurrent()。Impersonate()'作爲解決方法,但我仍然不明白爲什麼線程之間存在差異。如果'SecurityContext'沒有被捕獲,那麼一些線程仍然作爲模擬身份運行?我覺得還有更多。 – PoweredByOrange 2014-09-26 18:02:41