本文章是由機器翻譯。

內部 out CLR

探討 .NET Framework 4 安全性模型

Andrew Dai

.NET Framework 4 對 .NET 安全性模型有諸多更新,而得以更方便地針對部分受信任的程式碼裝載、保障和提供服務。 我們 overhauled 複雜的程式碼存取安全性 (CAS) 原則系統,是功能強大但難以使用且甚至更難以取得右。 我們也改善安全性透明效果] 模型時將帶大部分 Silverlight 改進 (這我討論有關最後一個十月:msdn.microsoft.com/magazine/cc765416.aspx) 在桌面架構的安全性強制執行。 最後,我們引進了一些新功能,透過已在公開其服務提供主應用程式和程式庫的開發人員更大的彈性。 以這些變更.NET Framework 4 出方便主機及文件庫沙箱管理程式碼,並安全地公開 (Expose) 服務的程式庫的更簡單、 改良的安全性模型。

在.NET Framework 安全性背景

之前投擲到任何特定功能,它會協助擁有上在.NET Framework 安全性如何運作的一些背景資料。 它具有的權限會限制部分受信任的程式碼,並且不同的 API 需要不同的權限,要成功地呼叫。 CAS 的目標是要確定未受信任的程式碼會以適當的權限執行,且 can’t 執行任何動作超過它的權限未授權的情況下。

我們可以把.NET 安全性模型做為可包含三個部分。 特定的改良功能已進行每個區域中,並根據這三個基本幾節來組織本文的其餘部分:

  • 原則 — 安全性原則會決定哪些權限給特定受信任的組件或應用程式。 Managed 程式碼有與其,可以描述何處載入程式碼從,發佈等等相關聯的辨識項物件。 辨識項可以用來判斷適當的使用權限 ; 結果稱為使用權限授權集。 傳統上.NET Framework 就有的 CAS 原則用作為全機器機制來控制這。 如同先前所述的 CAS 原則已被 overhauled 改的透過他們自己的安全性原則和 unhosted 的程式碼同位檢查與機器碼進行主機更大的彈性。
  • 沙箱隔離 — 沙箱隔離是實際的限制組件的程序或應用程式,以指定的使用權限授與組。 沙箱隔離慣用的方法是建立包含為載入的組件] 及 [豁免清單設定 (這些被授予完全信任) 的特定程式庫組件的權限授與沙箱應用程式網域。 有的 CAS 原則 obsoletion,與部分信任程式碼永遠取得沙箱這種方式在.NET Framework 4。
  • 強制 — 強制指的是會保留其沙箱僅限於未受信任的程式碼的機制。 強制 API 的適當使用可防止一個受信任的組件只是在不同、 更受信任的組件呼叫 API,並且這種方法行使較高的權限。 它也可讓主應用程式和程式庫開發人員公開 (Expose) 受控制、 限制存取提高權限的行為,並提供有意義的服務,部分受信任的程式碼。 層級 2 安全性透明度模型,比較容易更安全地執行這項操作。

主應用程式和程式庫的開發 (人員通常手動在手移) 的特定重要的向來.NET 安全性模型。 .NET 安全性模型的範例是 ASP.NET,SQL CLR 哪些兩者都裝載在受控制的環境和受限制的內容之內的 Managed 程式碼。 當載入部分信任的組件要像這些主機時,它以適當的使用權限授與集合建立沙箱應用程式定義域。 組件接著載入這個沙箱的網域。 主應用程式也提供程式庫是完全信任,但可從裝載程式碼呼叫的 API。 程式庫也載入沙箱定義域,但會明確地放在稍早提到的豁免清單上。 它們會依賴.NET Framework ’s 強制機制,以確保其提高權限的能力的存取緊密控制。

對於大部分受管理的應用程式開發人員這是所有魔法,發生在架構層級 — 甚至撰寫會在沙箱中執行的程式碼的開發人員 don’t 需要知道的安全性模型的運作方式的所有詳細資料。 此架構可確保沙箱的程式碼受限於使用 API 和主應用程式提供的能力。 .NET 安全性模型和 CAS 長已經被企業系統管理員和主應用程式和程式庫的開發人員的領域 ; 它們,我們做事比以前更容易。

原則

自.NET Framework,讓電腦和企業系統管理員微調了什麼執行階段視為信任或不受信任的一種方法開始提供有的 CAS 原則。 有的 CAS 原則時非常強大且允許非常細微的控制項,很難極為取得右及可能阻礙超過幫助。 電腦系統管理員可以鎖定特定的應用程式所需的使用權限 (下一個主要節所述,沙箱隔離),用完,許多人總會為什麼他們的應用程式突然停止運作一旦它們決定將它們放在網路共用上。 此外,CAS 原則設定 didn’t 向前移從一個版本的執行階段到另一個,讓某人在.NET Framework 1.1 中設定精緻自訂 CAS 原則必須取消會復原以手動方式針對.NET Framework 2.0。

安全性原則可以分割成兩個案例:裝載程式碼和安全性原則中的電腦或企業的安全性原則。 關於電腦原則通用語言執行階段安全性小組已決定執行階段已管理它,錯誤的位置,如原生程式碼顯然不是受制於其限制。 雖然它對主機能夠判斷其裝載的程式碼能做些什麼的合理,unhosted 的 exes,只需按下或從命令列執行應該行為就像其原生的複本分離出來一樣,(尤其是因為它們看起來相同使用者執行它們)。

全域的安全性原則的正確的位置是在作業系統層級這類原則會套用到原生的位置,並同樣 Managed 程式碼。 因此,我們鼓勵電腦系統管理員來看待預設像 Windows 軟體限制原則和停用整個機器 CAS 原則解析的解決方案。 其他案例,裝載程式碼的安全性原則仍然是在 Managed 程式碼世界十分有效。 主機安全性原則是現在更容易地管理,如,可能它將不再與用法相衝突任意電腦原則。

這表示您

一個,所有 unhosted Managed 程式碼執行以完全信任的根據預設值。 如果從您的硬碟或網路共用執行的.EXE,您的應用程式必須從相同的位置執行的原生應用程式會有的所有能力。 裝載程式碼不過,受仍然限於安全性決策的 (所有程式碼可以透過網際網路送達的方式都裝載案例的筆記 — ClickOnce 應用程式範例 — 因此這並不表示在網際網路上執行的程式碼是完全受信任) 主機。

對於許多應用程式這些變更大多是位於背景,且不會有任何已知的作用。 那些受變更所影響可能會遇到兩個問題。 第一個是某些 CAS 原則相關 API 會取代,許多與組件載入 (因此如果您執行這項操作根本上閱讀)。 第二個,和影響減少人員主要是主機、 將異質應用程式定義域 (沙箱隔離一節中所說明) 的 aren’t 依預設可使用的事實。

但我不做任何這! 如何我只使其運作?

或許您遭遇到看起來像這樣的錯誤或 obsoletion 郵件:

這個方法 [明確/隱含] 會使用已被廢棄的.NET Framework 的 CAS 原則。 如果要啟用基於相容性的理由有的 CAS 原則,請使用 NetFx40_LegacySecurityPolicy 組態參數。 請如需詳細資訊,參閱 [MSDN 文件的連結]。

基於相容性的理由我們提供可讓程序啟用它的 CAS 原則解析的組態參數。 您可能會藉由放置下列專案 ’s app.config 檔案中啟用有的 CAS 原則:

<configuration>
   <runtime>
      <!-- enables legacy CAS policy for this process -->
      <NetFx40_LegacySecurityPolicy enabled="true" />
   </runtime>
</configuration>

如果例外狀況被擲回從自己的程式碼下, 一節將說明何處開始尋求遷移。 如果它 isn’t 則組態參數會前往方式下, 一節 shouldn’t 直接套用到您。

受影響的 API

受影響的 API 可分為兩個群組:那些明確地使用 CAS 原則及那些隱含地使用它。 明確的使用方式,是明顯 — 它們傾向於居住 System.Security.Policy.SecurityManager 類別且看起來像 SecurityManager.ResolvePolicy。 這些 API 直接呼叫,或修改機器 ’s CAS 原則設定,且它們已經全部被取代。

隱含的使用方式,是較不明顯 — 這些傾向於組件載入或採取辨識項的應用程式網域建立。 有的 CAS 原則解析上這個辨識項,並且組件是載入使用產生的權限授與組。 因為有的 CAS 原則會依預設為關閉,就 doesn’t 合理來嘗試解決這個辨識項上的。 這類 API 的範例是 Assembly.Load (AssemblyName assemblyRef、 辨識項 assemblySecurity)。

有幾個為什麼會呼叫這類 API 的原因:

  1. 沙箱隔離 — Perhaps 知道從網際網路區域辨識項與呼叫該 Assembly.Load 多載會造成,因為組件載入與網際網路具名使用權限集合 (除非,也就是系統管理員變更此特定電腦或使用者的辨識項對應!)。
  2. 在多載上其他參數 — 或許您只想要取得特定參數只在這個多載上已存在。 在這種情況下您可能只被傳遞 Null 或 Assembly.GetExecutingAssembly ().Evidence 辨識項參數。

如果您嘗試沙箱,沙箱隔離一節將說明如何建立網際網路具名使用權限集合僅限於沙箱應用程式網域 您的組件可能然後載入該定義域,而且保證您所要的權限 (也就是不主旨來實現的系統管理員)。

我們新增到每個這些 API 所公開 (Expose) 所有必要的參數,但 don’t 公開為辨識項參數的多載中第二個案例。 遷移是簡單的剪下出辨識項引數為您的呼叫。 (請注意傳遞 Null 辨識項到過時的 API 仍然適用同時也因為 doesn’t 導致 CAS 原則評估)。

一額外件事来注意的是,如果您從遠端位置執行組件載入 (也就是 Assembly.LoadFrom(“http://...”)),您最初取得一個 FileLoadException 除非設定下列的組態參數。 這麼做是因為這個呼叫會 ’ve 沙箱在過去組件。 與消失的 CAS 原則,是完全受信任!

<configuration>
   <runtime>
      <!-- WARNING: will load assemblies from remote locations as fully
         trusted! -->
      <loadFromRemoteSources enabled="true" />
   </runtime>
</configuration>

若要這樣,但不開啟整個程序的這個參數的其他方式為使用新 Assembly.UnsafeLoadFrom API,以參數集的作用就像是 LoadFrom 一樣。 如果您只想要啟用遠端負載在某些地方或 don’t 擁有主要的應用程式,這會很有用。

與圖片中的整個機器 CAS 原則的組件辨識項並決定適當的使用權限集合的所有檢查都留到主機 Managed 程式碼。 沒有它干擾 (除了從任何作業系統的安全性原則) 其安全性決策的頂端複雜系統,主機可以自由地指定它自己的權限。 現在它 ’s 將這些權限指派給部分信任組件的時間。

沙箱

我們可以透過主機 ’s 安全性原則來判斷正確的權限授權集,讓部分信任組件。 現在我們需要一個簡單且有效的方法,將會將這個組件載入,會限定為該特定的授權集的環境。 特別使用簡單的沙箱 CreateDomain 多載的沙箱隔離並僅具有。

在過去的沙箱隔離

與舊的 CAS 原則模型已有可能建立異質應用程式網域在網域中的每個組件位置有它自己的權限設定。 使用網際網路區域辨識項組件載入可能會導致兩個或多個組件載入至完全信任執行載入的組件相同的網域不同的部分信任層級。 此外,應用程式定義域可以擁有它自己辨識項提供它自己的使用權限集。

有這種模型的幾個問題:

  • 使用權限集合授與組件是 CAS 原則而定,如幾個原則層級會交集來計算最終的使用權限集合。 因此,很可能得到比預期較少的權限。
  • 方法類似於前一個點,在組件的辨識項評估是跨機器、 使用者和執行階段 (設定 didn’t 向前移動新版本的執行階段 CAS 原則) 的偶數版本可能有不同的 CAS 原則。 因此,它 wasn’t 永遠明顯取得組件的使用權限授與集合。
  • 部分信任組件通常不會為了強化,使 「 中間信任 」 組件容易受 「 最低信任 」 的組件的安全性檢查。  組件可自由地與輕易地彼此呼叫,所以有許多都擁有不同的能力會成為嚴重的問題就是從安全性觀點來看。 有人可以確定呼叫從不同信任層級的組件的每一組合是安全嗎? 它是快取資訊從中間的信任層絕對安全嗎?

因為這些問題的我們介紹同類型的應用程式網域這包含只有兩個使用權限授與集合 (部分信任和完全信任),來建立和原因的相關極為簡單的概念。 同質網域,以及如何建立它們,本章節的稍後說明。

沙箱隔離的另一個常用機制是 PermitOnly 使用而拒絕也就是堆疊查核行程修飾元,該清單特定允許的限 (、 什麼都沒有更多),而不允許特定權限分別。 好像有用說,「 我只想要具有的權限的呼叫端 x 和 y,才能呼叫這個 API 」,「 為一個 API 我想要或拒絕的權限到我的所有呼叫端 」不過,這些修飾詞 並不實際變更使用權限授與集合的特定組件 ,這意味著它們可以被聲明離開因為 所有他們是否被截距要求 。 作用中的這範例 的 圖 1 所示。

圖 1 A 呼叫堆疊表示與沙箱隔離在嘗試拒絕

無紅色 Assert 要求叫用 [拒絕],且堆疊查核行程 (Stack Walk) 就會終止。 使用中紅色的判斷提示時,但是,[拒絕永遠不會叫時,為不受信任具有已判斷要求離開。 (附註:呼叫堆疊向下成長。 API 並不是在架構中的實際 API)。基於這個原因拒絕已在.NET Framework 4,被取代,因為使用它永遠是 (PermitOnly 是仍然周圍因為它可以合法使用在少數角情況下,但是是通常不建議使用) 的安全性漏洞。 請注意它可以重新啟動使用 NetFx40_LegacySecurityPolicy 參數上述原則節所述。

今天沙箱隔離

對於.NET] Framework 我們使用的隔離單位會為應用程式定義域。 每個部分信任應用程式網域有除了特別列於完全信任豁免清單上,或從全域組件快取載入所有組件載入到它取得一個單一的使用權限授與集合。 建立這個網域是很簡單 —.NET Framework 提供簡單的沙箱會在所有項目讓您的 API 需要建立網域:

AppDomain.CreateDomain( string friendlyName,
 
                        Evidence securityInfo,
                        
                        AppDomainSetup info,
                        
                        PermissionSet grantSet,
                        
                        params StrongName[] fullTrustAssemblies);

位置參數是:

  • friendlyName — 應用程式網域的好記的名稱。
  • securityInfo — 與應用程式定義域的辨識項相關聯。 這 isn’t 用於 CAS 原則解析顯然,但有可能用來儲存之類的發行者資訊。
  • 資訊 — 應用程式定義域初始化資訊。 這必須包括,最小,一個 ApplicationBase 代表部分信任組件的所在位置的儲存區。
  • grantSet — 「 權限授與這個網域除了在完全信任清單上,或在全域組件快取中的所有已載入組件的集合。
  • fullTrustAssemblies — StrongNames 授與完全信任 (exempt 從部分信任) 的組件的清單。

一旦建立網域可以在一個 MarshalByRefObject 上呼叫 AppDomain.CreateInstanceAndUnwrap 部分信任組件中,並 的 圖 2 所示,然後呼叫到開始進行,關閉其進入點方法。

圖 2 的 內部執行的部分信任程式碼的沙箱

PermissionSet permset = new PermissionSet(PermissionState.None);
ps.AddPermission(new SecurityPermission(
   SecurityPermissionFlag.Execution));
AppDomainSetup ptInfo = new AppDomainSetup();
ptInfo.ApplicationBase = ptAssemblyStore;
 
AppDomain sandboxedDomain = AppDomain.CreateDomain(
   "Sandbox",
   AppDomain.CurrentDomain.Evidence,
   ptInfo,
   permset);
 
// assume HarnessType is in the GAC and a MarshalByRef object

HarnessType ht = sandboxedDomain.CreateInstanceAndUnwrap(
   typeof(HarnessType).Assembly.FullName,
   typeof(HarnessType).FullName)
   as HarnessType;
 
ht.LoadPTEntryPoint();

’s 它 ! 使用幾行程式碼我們現在必須沙箱中它執行的部分信任程式碼。

因此不 ’s 新.NET Framework 2.0 實際上已加入此 CreateDomain API。 不過,它 ’s 值得一提如現在 ’s 沙箱管理程式碼,唯一真正支援的方法。 您可以看到使用權限集合直接傳遞,所以沒有辨識項已載入的組件至這個網域中將被評估 ; 您確切知道哪些每一個載入的組件即將要取得。 此外,使用真實的隔離界限包含部分信任程式碼中做出安全性假設非常有用。 使用簡單的沙箱 CreateDomain API,沙箱會成為更明顯、 一致而且安全 — 協助讓處理不受信任的所有事情更容易撰寫程式都碼。

強制執行

這個時候我們有適當的權限授與我們部分信任組件的集合,並已載入組件至適當的沙箱。 太棒了! 部分信任的程式碼,要是我們實際想要公開 (Expose) 一些提升不過,功能? 比方說我可能不想讓網際網路應用程式的完整檔案系統存取,但是我 don’t 介意如果它會讀取並寫入從已知的暫存資料夾。

您讀取 Silverlight 安全性 ( msdn.microsoft.com/magazine/cc765416.aspx ) 上的最後一年 ’s 欄知道完全如何這個問題已解決的該平台 — 透過安全性透明度模型亦整齊地分割程式碼到三個桶。 我 ’m 快樂說模型的 Silverlight ’s 評審現在是作用中在.NET Framework 4 上。 這表示較簡單的模型 Silverlight 平台程式庫 enjoyed 優點現在是部分信任程式庫的非 Microsoft 開發人員可以使用的。 進入,而其他改良,強制空間之前不過,我討論從我們主要的強制機制之前。

在過去的強制

安全性透明已實際上在.NET Framework 2.0 引入了但主要是為的稽核機制,而不是其中一個 (新的安全性透明度模型是兩者) 的強制提供服務,提到最後一年。 在較舊的模型或層級 1 安全性透明效果,違規做不資訊清單本身為硬碟失敗 — 它們 (就像 p/呼叫機器碼) 的許多導致權限要求。 如果透明的組件找不到在其授與集合中有 UnmanagedCode,它仍然可以請繼續進行並執行它做什麼 (違反透明度規則處理程序中的)。 此外,透明度檢查停止於組件界限,進一步降低其強制效果。

在.NET Framework 2.0 中,則為 True 強制附 LinkDemands 形式 — 存回的呼叫組件授與集合所包含指定的使用權限的 JIT 時間檢查。 所有康復個良好,但此模型基本上是所需程式庫開發人員来用於稽核和強制執行是多餘的兩個不同的機制。 Silverlight 模型合併,並簡化這些兩個概念是自然進展從這個狀態,而變得什麼現在是層級 2 安全性透明。

層級 2 安全性透明度

層級 2 安全性透明度是安全在低信任層級的環境中執行的程式碼和 isn’t 的程式碼分開的強制機制。 在一簡單地說,它可以執行安全性機密作業 (嚴重) 像檔案作業的程式碼和 can’t (透明) 的程式碼之間繪製障礙。

安全性透明度模型分隔成三個桶的程式碼:透明重大及重要的安全 下圖 圖 3 說明這些桶。 (注意:綠色箭號表示允許的呼叫 ; 紅色箭號表示那些 aren’t。 self-loops 有效同時也但不是顯示)


圖 3 的 安全性透明度模型

典型的桌面應用程式層級 2 透明度模型並不會明顯影響 — 並沒有任何安全性附註,而不是沙箱的程式碼會假設為要徑,因此是不受限制。 但是,因為它是要徑,就 off-limits 部分信任呼叫者。 因此,開發人員 don’t 有部分信任的案例 won’t 需擔心還得公開為部分信任的任何項目。

沙箱應用程式的相反為真 — 載入沙箱應用程式定義域的組件會被假設為完全透明 (即使它附帶否則指定的註解)。 如此可確保部分信任程式碼無法嘗試提升透過判斷提示權限,或呼叫原生程式碼 (在完全信任對等動作)。

暴露在部分信任呼叫者與桌上型電腦或沙箱應用程式不同的程式庫必須深切瞭解其安全性需求和透過其能力和它們公開有更多的彈性。 典型的部分信任呼叫程式庫應該具有最基本的安全的要徑 API 主要是透明和要徑的程式碼。 關鍵程式碼時不受限制的是已知從部分信任程式碼無法存取。 透明的程式碼可從部分信任程式碼呼叫,但很安全。 它提供了提高權限的功能和 utmost 必須小心以確保轉換透過重大的程式碼之前,先驗證其呼叫者時,安全重大的程式碼是非常危險。

安全性透明屬性和其行為是列,而 的 圖 4 所述。 請記住最高範圍] 屬性會套用針對所有引入 API 下它,不論這些 API 是否具有自己的註解。 AllowPartiallyTrustedCallers 是不同,因為它要延遲,並接受較低層級屬性。 (注意:下表描述屬性以及套用在組件、 型別或成員層級時的行為。 屬性僅套用於表示子類別的引入 API 及覆寫會受制於繼承規則且可能會不同透明度的層次)。

圖 4 安全性透明屬性] 與 [及其表現方式

您記得上次十月 ’s 發行項可能會注意到更多或更少屬性運作,他們在 Silverlight 中做相同的方式。 您可能會同時別忘了不同類型的程式碼與相關聯的特定的繼承規則。 那些也是在桌面中的效果。 如需有關繼承規則和其他方面的層級 2 透明度的詳細資訊,看一下去年 ’s 文章 「 安全性在 Silverlight 2 」 ( msdn.microsoft.com/magazine/cc765416.aspx )。

條件式 AllowPartiallyTrustedCallers

AllowPartiallyTrustedCallers 屬性 (APTCA) 表示組件是可能公開敏感的安全性功能,為部分信任的程式庫。 APTCA 程式庫組件是通常寫入結合與主機,因為主機通常想要公開 (Expose) 其裝載環境的特定功能。 一個主要的範例是公開 System.Web 命名空間,可能會在各種信任層級其裝載程式碼的 ASP.NET。

不過,’s 可決定要將其載入任何主應用程式中的部分信任的組件方法上放置 APTCA,這可將責任如果組件作者 doesn’t 知道該組行為在不同的主機的方式。 因此,主應用程式開發人員有時候會想部分信任載入自己網域中時,只可其程式庫。 ASP.NET 會完全此,並在較早版本中已經有 LinkDemands 用於其 API 的特殊權限。 雖然這適用於它會使每個人都建置在他們必須滿足該 LinkDemand 防止從正在透明這些向上堆疊組件的頂端。

要解決這個問題我們引進了 [設定格式化的條件 APTCA] 功能可讓部分信任呼叫者只能在未啟用的主機 (透過清單) 中公開 API 的程式庫。

主應用程式和程式庫的特定的角色是:

  • 文件庫只限定 AllowPartiallyTrustedCallers 屬性具有參數 PartialTrustVisibilityLevel 列舉。 範例:
[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel= PartialTrustVisibilityLevel.NotVisibleByDefault)]
  • 這個屬性基本上寫著程式庫不可以從部分信任呼叫除非主應用程式會有它在其允許-清單上,以下提及。 值為 VisibleToAllHosts 會使文件庫可以從部分信任中的所有主機呼叫。

  • 主應用程式指定組部分信任可見件,每透過允許清單的應用程式定義域。 此清單通常會填入透過提供給主應用程式組態檔。 重要的是来牢記在心是無條件的 APTCA 組件像基本架構文件庫執行沒有要加入至 (參閱重要要牢記在心的是如果啟用設定格式化的條件 APTCA 組件,您應該啟用相依條件式 APTCA 組件以及其可轉移終止。 這個清單。 否則,您可能會得到異常行為如原始組件會嘗試呼叫假設是可存取,但是真正 aren’t 的 API)。

更容易地保障安全

很多事情發生安全性模型中的.NET Framework 4。 有的 CAS 原則已被停用預設離開所有安全性原則決策到主機,並與原生 exes 授予 unhosted Managed 的 exes 行為同位檢查。 停用的 CAS 原則已也停用異質性應用程式定義域,最後進行有效率的簡單沙箱 CreateDomain 多載部分信任組件的主要支援沙箱隔離機制。 安全性透明度模型所描述的最後一個十月的 Silverlight ’s 改良有也前來在桌面為部分信任程式庫開發人員提供具有相同的效率和 cleanliness 為 Silverlight 平台所提供的好處。

我們製作這些變更,例如大部分的應用程式會繼續運作為它們有前,但主控件和程式庫開發人員那裡會找到較簡單的模型,以處理的方式 — 一個可更具決定性、 更容易使用並因此,安全更容易。

Andrew Dai 是 CLR 安全性小組的程式管理員。 如需如何使用本文中所提到的功能詳細、 深入資訊,請造訪 CLR 團隊部落格 ( blogs.msdn.com/clrteam ) 和 Shawn Farkas ’.NET 安全性部落格 ( blogs.msdn.com/shawnfa )。