要求

更新:2007 年 11 月

您可以使用安全性宣告式或命令式要求呼叫,以指定直接或間接呼叫端存取類別庫時必須擁有的使用權限。直接呼叫端會明確地呼叫您類別庫的靜態或執行個體方法,而間接呼叫端則會以呼叫您類別庫的另一個類別庫來呼叫您類別庫的靜態或執行個體方法。當您使用要求時,只有在所有的直接或間接呼叫端都擁有要求指定的使用權限的情況下,才會執行包含您程式碼的應用程式。當您類別庫使用的受保護資源不想由未受信任的程式碼存取時,要求就非常有用。要求可以放入使用命令式或宣告式語法的程式碼內。

請注意 .NET Framework 中大部分的類別都已和要求關聯,因此當您使用類別存取受保護的資源時並不需要再設定額外的要求。例如,StreamWriter 類別會在 FileIOPermission 開啟時自動為它設定一個安全性要求。如果您在使用 StreamWriter 類別時設定了一個 FileIOPermission 要求,將會產生一個多餘且無效的堆疊查核行程。您應該使用要求以保護需要自訂使用權限的自訂資源。

要求可以是宣告式的,也可以是命令式的。

堆疊查核行程

要求會透過執行分析 (稱為堆疊查核行程 (Stack Walk)) 的方式強制安全性,在該分析中,目前呼叫堆疊的每個呼叫函式 (或堆疊框架 (Stack Frame)) 都是針對指定的使用權限進行檢查。觸發 (Trigger) 要求時會發生下列動作。

  • 堆疊查核行程會在呼叫端堆疊框架中開始執行,而不是在發生要求的目前堆疊中開始。例如,如果方法 A 呼叫方法 B 而方法 B 具有要求,則堆疊查核行程會在方法 A 的堆疊框架中開始執行。方法 B 一定不會評估為堆疊查核行程的一部分。

  • 堆疊查核行程會持續進行整個呼叫堆疊,直到到達堆疊的程式進入點 (Entry Point) (通常是 Main 方法) 或找到類似判斷提示 (Assert) 的堆疊查核行程修飾詞 (Modifier) 為止。如需堆疊查核行程修飾詞的詳細資訊,請參閱覆寫安全性檢查

  • 當相同的堆疊框架上出現相同使用權限的要求和堆疊查核行程修飾詞 (例如,判斷提示) 時,要求的優先順序較高。

  • 宣告式和命令式語法的表現行為上沒有差別。

  • 請注意,放置在程式進入點的要求絕對不會進行評估,因為堆疊查核行程一定會在呼叫堆疊框架中開始,但是在這個狀況中,沒有這類的呼叫框架可供評估。因此,放置在程式進入點的要求永遠會順利完成。

宣告式要求

宣告式要求會將資訊放入使用屬性的程式碼其中繼資料內。您可以使用宣告式語法將要求放在程式碼的類別或方法等級。

如果您將一個宣告式安全性檢查置於類別等級上,它將會套用至每一個類別成員。然而,如果您將一個宣告式安全性檢查置於成員等級上,它只會套用至該成員,並覆寫在類別等級上所指定的使用權限 (如存在時)。例如,假設您在類別等級上指定 PermissionA,並在該類別的 Method1 上指定 PermissionB。當 Method1 被呼叫時,安全性檢查將只會尋找 PermissionB,但類別的其他方法仍會要求 PermissionA。

以下的範例會在 ReadData 方法的所有呼叫端上放入一個 CustomPermission 自訂使用權限的宣告式要求。這個使用權限是任意指定的自訂使用權限,並不存在於 .NET Framework 中。這個自訂使用權限使用一個單獨定義的 CustomPermissionAttribute 來設定需求。在這個範例中,它會取得一個 SecurityAction.Demand 旗標,以指定屬性將執行的要求類型。

<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted := True)>Public Shared Function  ReadData() As String
   'Read from a custom resource.
End Function
[CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
public static string ReadData()
{
   //Read from a custom resource.
}

命令式要求

命令式要求會建立一個使用權限物件的新執行個體並呼叫該物件的 Demand 方法,而將它放在您程式碼的方法等級。命令式語法不可在類別等級上放入要求。

放在程式碼內的命令式要求可以有效地協助保護 Demand 方法所呼叫方法中的其餘程式碼。執行 Demand 時會執行安全性檢查;如果安全性檢查失敗,會擲回 SecurityException,且在攔截到 SecurityException 並予以處理之前,不會執行該方法或成員中的其餘程式碼。

下列範例使用命令式語法,在自訂使用權限 CustomPermission 的所有呼叫端上放置要求。這個程式碼會建立一個 CustomPermission 類別的新執行個體,並將 PermissionState.Unrestricted 旗標傳遞給建構函式。然後再呼叫 Demand 方法。

Public Shared Sub ReadData()
   Dim MyPermission As New CustomPermission(PermissionState.Unrestricted)
   MyPermission.Demand()
   'Read from a custom resource.
End Sub  
public static void ReadData()
{
   CustomPermission MyPermission = new CustomPermission(PermissionState.Unrestricted);
   MyPermission.Demand();

   //Read from a custom resource.
}
注意事項:

要求作業的最佳化行為在 64 位元和 32 位元的平台上有所不同。在 64 位元的平台上,要求不會檢查組件的授權集,而該組件則包含沒有出現其他呼叫組件時的要求。不過,此最佳化並不會提升權限,因為出現呼叫組件時仍會執行堆疊查核行程。在 32 位元的平台上,要求作業會檢查其中包含要求和所有呼叫組件的組件授權集。

請參閱

概念

安全性要求

建立您自己的程式碼存取使用權限

加入宣告式安全性支援

撰寫安全類別庫

參考

SecurityException

其他資源

使用屬性擴充中繼資料

程式碼存取安全性