安全性透明的程式碼,層級 2
層級 2 透明度是 .NET Framework 4 版引入的。 這個模型的三個原則是透明程式碼、安全性安全關鍵程式碼和安全性關鍵程式碼。
透明程式碼 (包括以完全信任執行的程式碼) 只能呼叫其他透明程式碼或安全性安全關鍵程式碼。 它只能執行定義域之部分信任使用權限集合 (如果存在的話) 所允許的動作。 透明程式碼無法進行下列作業:
執行 Assert 或提高權限。
包含不安全或無法驗證的程式碼。
直接呼叫關鍵程式碼。
呼叫機器碼或含有 SuppressUnmanagedCodeSecurityAttribute 屬性的程式碼。
呼叫 LinkDemand 所保護的成員。
繼承自關鍵型別。
此外,透明方法無法覆寫關鍵虛擬方法或實作關鍵介面方法。
安全關鍵程式碼受到完全信任,但是可由透明程式碼呼叫。 它會公開完全信任程式碼的有限介面區。正確性和安全性驗證會在安全關鍵程式碼中進行。
雖然安全性關鍵程式碼可以呼叫任何程式碼而且受到完全信任,但是無法由透明程式碼呼叫。
此主題包括下列章節:
使用範例和行為
覆寫模式
繼承規則
其他資訊和規則
使用範例和行為
若要指定 .NET Framework 4 規則 (層級 2 透明度),請針對組件使用下列附註:
[assembly: SecurityRules(SecurityRuleSet.Level2)]
若要鎖定 .NET Framework 2.0 規則 (層級 1 透明度),請使用下列附註:
[assembly: SecurityRules(SecurityRuleSet.Level1)]
如果您沒有為組件加上附註,預設將使用 .NET Framework 4 規則。 不過,建議的最佳作法是使用 SecurityRulesAttribute 屬性,而非仰賴預設值。
組件範圍的附註
下列規則適用於在組件層級使用屬性:
無屬性:如果您沒有指定任何屬性,執行階段就會將所有程式碼解譯為安全性關鍵的,但是安全性關鍵違反繼承規則的程式碼除外 (例如,在覆寫或實作透明虛擬或介面方法時)。 在這些情況下,這些方法都是安全關鍵方法。 不指定屬性會導致 Common Language Runtime 為您決定透明度規則。
SecurityTransparent:所有程式碼都是透明的。整個組件將不會進行任何需要權限或不安全的作業。
SecurityCritical:這個組件中之型別所引入的所有程式碼都是關鍵的。所有其他程式碼則為透明的。 這個案例與不指定任何屬性很相似。不過,Common Language Runtime 不會自動決定透明度規則。 例如,如果您覆寫虛擬或抽象方法,或是實作介面方法,該方法預設為透明的。 您必須明確將此方法加註為 SecurityCritical 或 SecuritySafeCritical。否則,系統將在載入時擲回 TypeLoadException。 當基底類別和衍生類別都位於相同的組件時,這項規則也適用。
AllowPartiallyTrustedCallers (僅限層級 2):所有程式碼都預設為透明的。 不過,個別的型別和成員可以有其他屬性。
下表會比較層級 2 與層級 1 的組件層級行為。
組件屬性 |
層級 2 |
層級 1 |
---|---|---|
部分信任組件無屬性 |
型別和成員預設為透明的,但是可能為安全性關鍵或安全性安全關鍵的。 |
所有型別和成員為透明。 |
無屬性 |
不指定屬性會導致 Common Language Runtime 為您決定透明度規則。 所有型別和成員都是安全性關鍵的,但是安全性關鍵違反繼承規則的程式碼除外。 |
在完全信任的組件 (位於全域組件快取中或在 AppDomain 中識別為完全信任) 上,所有型別都是透明的,而且所有成員都是安全性安全關鍵的。 |
SecurityTransparent |
所有型別和成員為透明。 |
所有型別和成員為透明。 |
SecurityCritical(SecurityCriticalScope.Everything) |
不適用。 |
所有型別和成員為安全性關鍵。 |
SecurityCritical |
這個組件中之型別所引入的所有程式碼都是關鍵的。所有其他程式碼則為透明的。 如果您覆寫虛擬或抽象方法,或是實作介面方法,就必須明確將此方法加註為 SecurityCritical 或 SecuritySafeCritical。 |
所有程式碼都預設為透明的。 不過,個別的型別和成員可以有其他屬性。 |
型別和成員附註
套用至某個型別的安全性屬性也會套用至該型別所引入的成員。 不過,這些屬性不會套用至基底類別或介面實作的虛擬或抽象覆寫。 下列規則適用於在型別和成員層級使用屬性:
SecurityCritical:型別或成員是關鍵的,而且只能由完全信任程式碼呼叫。 在安全性關鍵型別中引入的方法是關鍵的。
重要事項 在基底類別或介面中引入並且在安全性關鍵類別中覆寫或實作的虛擬和抽象方法預設為透明的。它們必須識別為 SecuritySafeCritical 或 SecurityCritical。
SecuritySafeCritical:型別或成員是安全關鍵的。 不過,此型別或成員可以從透明 (部分信任) 程式碼呼叫,而且其功能與任何其他關鍵程式碼一樣。 基於安全性,您必須稽核此程式碼。
回到頁首
覆寫模式
下表顯示層級 2 透明度所允許的方法覆寫。
基底虛擬/介面成員 |
覆寫/介面 |
---|---|
Transparent |
Transparent |
Transparent |
SafeCritical |
SafeCritical |
Transparent |
SafeCritical |
SafeCritical |
Critical |
Critical |
回到頁首
繼承規則
在本節中,下列順序是根據存取和功能指派給 Transparent、Critical 和 SafeCritical 程式碼。
Transparent < SafeCritical < Critical
型別的規則:由左至右執行,存取限制變得更嚴格。 衍生型別的限制至少必須與基底型別一樣嚴格。
方法的規則:衍生方法無法變更基底方法的存取範圍。 就預設行為而言,沒有加上附註的所有衍生方法都是 Transparent。 如果覆寫方法沒有明確加註為 SecurityCritical,關鍵型別的系出物件會導致系統擲回例外狀況。
下表顯示允許的型別繼承模式。
基底類別 |
衍生類別可為 |
---|---|
Transparent |
Transparent |
Transparent |
SafeCritical |
Transparent |
Critical |
SafeCritical |
SafeCritical |
SafeCritical |
Critical |
Critical |
Critical |
下表顯示不允許的型別繼承模式。
基底類別 |
衍生類別不可為 |
---|---|
SafeCritical |
Transparent |
Critical |
Transparent |
Critical |
SafeCritical |
下表顯示允許的方法繼承模式。
基底方法 |
衍生方法可為 |
---|---|
Transparent |
Transparent |
Transparent |
SafeCritical |
SafeCritical |
Transparent |
SafeCritical |
SafeCritical |
Critical |
Critical |
下表顯示不允許的方法繼承模式。
基底方法 |
衍生方法不可為 |
---|---|
Transparent |
Critical |
SafeCritical |
Critical |
Critical |
Transparent |
Critical |
SafeCritical |
注意事項 |
---|
這些繼承規則適用於層級 2 型別和成員。層級 1 組件中的型別可以繼承自層級 2 安全性關鍵型別和成員。因此,層級 2 型別和成員必須針對層級 1 繼承者具有不同的繼承要求。 |
回到頁首
其他資訊和規則
LinkDemand 支援
層級 2 透明度模型會將 LinkDemand 取代成 SecurityCriticalAttribute 屬性。 在舊版 (層級 1) 程式碼中,LinkDemand 會被自動視為 Demand。
反映
叫用關鍵方法或讀取關鍵欄位就會觸發完全信任的要求 (就如同您叫用私用方法或欄位一樣)。 因此,完全信任程式碼可以叫用關鍵方法,而部分信任程式碼則無法叫用。
下列屬性已經加入至 System.Reflection 命名空間,以便判斷型別、方法或欄位是否為 SecurityCritical、SecuritySafeCritical 或 SecurityTransparent:IsSecurityCritical、IsSecuritySafeCritical 和 IsSecurityTransparent。 您可以使用這些屬性 (Property) 來判斷透明度,方法是使用反映,而非檢查屬性 (Attribute) 是否存在。 透明度規則很複雜,而且檢查屬性是否存在可能不足夠。
注意事項 |
---|
SafeCritical 方法會針對 IsSecurityCritical和 IsSecuritySafeCritical 傳回 true,因為 SafeCritical 確實是關鍵的 (雖然它與關鍵程式碼具有相同的功能,但是可從透明程式碼呼叫)。 |
動態方法會繼承它們所附加之目標模組的透明度,但是不會繼承型別的透明度 (如果它們附加至型別的話)。
在完全信任中略過驗證
若為完全信任的透明組件,您就可以在 SecurityRulesAttribute 屬性 (Attribute) 中,將 SkipVerificationInFullTrust 屬性 (Property) 設定為 true,藉以略過驗證:
[assembly: SecurityRules(SecurityRulesSet.Level2, SkipVerificationInFullTrust = true)]
SkipVerificationInFullTrust 屬性預設為 false,因此這個屬性必須設定為 true,才能略過驗證。 您應該僅針對最佳化目的進行此作業。 您應該使用 PEVerify 工具中的 transparent 選項,確認組件中的透明程式碼是否可驗證。
回到頁首