2017-04-13 78 views
1

我正在編寫一個自定義的.Net應用程序,該應用程序利用聲明來實現安全性,因爲我們跨越了許多界限 - Web,API,批處理等等。在開發過程中,有些時候我會通過Chrome登錄後在系統中創建一些內容,然後我將通過Edge中的其他帳戶去測試新創建的項目,並以某種方式HttpContext.Current.User.Identity對應於我的Chrome會話。我在後臺設置了Thread.CurrentPrincipal,但我的理解一直是,所有到IIS的請求都會產生一個新線程,所以我無法弄清楚爲什麼Edge請求正在處理,就好像它們是Chrome請求一樣。是IISExpress單線程?

是否有可能因爲Visual Studio是在調試模式下,它的分享這些信息?

+0

_「......要求到IIS中創建新的線程...」 _ - 最有可能的請求會在下一可用線程池線程。所以線程ID隨着時間的推移將不會是唯一的 – MickyD

+0

@rubyhaus實際上你的擔心是什麼,我假設什麼時候在chrome中有同一用戶的請求,你不想讓他在其他瀏覽器中,這是你正在嘗試實現 ? – Webruster

回答

4

是,IIS(因此IISExpress,這是IIS打包在「應用」格式)是多線程。但是,你做出了一些不正確的假設。

首先,沒有。一個新的請求不產生一個新的線程,它運行在一個線程池線程上,並且這些線程池在前一個請求完成後重新使用(或者,正如你在一分鐘內看到的那樣,當一個異步請求等待時)。

其次,你不應該設置Thread.CurrentPrincipal,因爲不僅在IIS多線程,它是異步的。這意味着如果你的線程等待,當它恢復時,它可能會運行在與它開始的線程不同的線程上。

第三,Thread.CurrentPrincipal通常是工作進程(或程序池)的身份的身份,改變這改變了整個線程下運行的安全上下文。一個更好的選擇是使用WindowsImpersonationContext類做模擬(這是我假設你正在嘗試做)。

WindowsIdentity clientId = (WindowsIdentity)User.Identity; 

// When 'using' block ends, the thread reverts back to previous Windows identity, 
// because under the hood WindowsImpersonationContext.Undo() is called by Dispose() 
using (WindowsImpersonationContext wic = clientId.Impersonate()) 
{ 
    // do your work that needs the identity 
} 

如果你需要設置你通常應該使用HttpContext.Current.User,而不是一個Thread.CurrentPrincipal中自定義主體。

+0

我在網頁設置了'HttpContext.Current.User',但是沒有在任何地方引用'System.Web',我該如何讓底層庫(主要是業務層)知道經過身份驗證的用戶是誰?我試圖避免引用System.Web,因爲並非所有東西都會使用Web組件。我一直認爲來自Microsoft的Membership API來設置ThreadPrincipal,因此走這條路。 – RubyHaus

+1

@RubyHaus - 是的,微軟的代碼往往做了很多的事情,我們,我們一般不應該,因爲MS知道它在做什麼,並妥善處理清理和邊緣的情況下,我們往往不知道有足夠的瞭解的內部,它通常是最好避免它們。你在做某種自定義身份驗證嗎?你能否簡單地將信息從網絡層傳遞給圖書館? –

+0

我希望有一個更加無縫的方式去做,但我可以想出辦法做到這一點。謝謝您的幫助! – RubyHaus