確認要求

セキュリティ確認要求呼び出しを宣言的または強制的に使用することで、直接または間接の呼び出し元が、作成したライブラリにアクセスするために持っている必要があるアクセス許可を指定できます。直接の呼び出し元は、ライブラリの静的メソッドまたはインスタンス メソッドを明示的に呼び出しますが、間接の呼び出し元は、そのライブラリを呼び出す別のライブラリの静的メソッドまたはインスタンス メソッドを呼び出します。確認要求を使用すると、作成したコードを含んだアプリケーションは、コードの直接および間接のすべての呼び出し元がその確認要求で指定されたアクセス許可を持っている場合にだけ実行されます。確認要求は、作成したクラス ライブラリが、信頼されていないコードからのアクセスを避ける必要がある、保護されたリソースを使用している場合には特に有用です。確認要求は、強制構文または宣言構文のいずれかを使用してコード内に配置できます。

.NET Framework のほとんどのクラスには既に確認要求が関連付けられているため、保護されているリソースにアクセスするクラスを使用するときに、追加の確認要求を作成する必要はありません。たとえば、StreamWriter クラスを開くと、FileIOPermission を要求するセキュリティ確認要求が自動的に生成されます。そのため、StreamWriter クラスを使用するときに FileIOPermission に対する確認要求をわざわざ作成すると、重複した非効率なスタック ウォークが行われることになります。カスタム アクセス許可を必要とするカスタム リソースを保護するには、確認要求を使用する必要があります。

確認要求は、宣言的または強制的に実行できます。

スタック ウォーク

確認要求は、スタック ウォークという分析を実行することによってセキュリティを適用します。この分析では、現在の呼び出し履歴のすべての呼び出し関数 (またはスタック フレーム) が指定されたアクセス許可に対してチェックされます。確認要求がトリガされると、次の処理が行われます。

  • スタック ウォークは、確認要求が発生している現在のスタックではなく、呼び出し元のスタック フレームで開始されます。たとえば、メソッド A がメソッド B を呼び出し、メソッド B に確認要求が発生している場合、スタック ウォークはメソッド A のスタック フレームから開始されます。このスタック ウォークでは、メソッド B は評価されません。

  • スタック ウォークは、スタックのプログラム エントリ ポイント (通常は Main メソッド) に到達するか、またはアサートなどのスタック ウォーク修飾子が見つかるまで呼び出し履歴を処理します。スタック ウォーク修飾子については、「セキュリティ チェックのオーバーライド」を参照してください。

  • 同じアクセス許可に対する確認要求とスタック ウォーク修飾子 (アサートなど) が同じスタック フレームにある場合は、確認要求が優先されます。

  • 宣言的および強制的な構文における動作の違いはありません。

  • スタック ウォークは常に呼び出し元のスタック フレームから開始されるため、プログラム エントリ ポイントに置かれた確認要求は評価されません。ただし、この場合は評価する呼び出し元のフレームはありません。したがって、プログラム エントリ ポイントに置かれた確認要求は常に成功します。

宣言的な確認要求

宣言的な確認要求は、属性を使用してコードのメタデータに情報を配置します。宣言構文を使用すると、確認要求をコードのクラス レベルまたはメソッド レベルに配置できます。

宣言セキュリティ チェックをクラス レベルに配置すると、そのセキュリティ チェックはクラスの各メンバに適用されます。ただし、宣言セキュリティ チェックをメンバ レベルに配置すると、セキュリティ チェックはそのメンバだけに適用され、クラス レベルでアクセス許可が指定されていても、そのアクセス許可はオーバーライドされます。たとえば、クラス レベルではアクセス許可 A が必要であると指定し、そのクラスのメソッド 1 にはアクセス許可 B が必要であると指定したとします。メソッド 1 が呼び出された場合、セキュリティ チェックはアクセス許可 B についてだけ行われますが、このクラスの他のメソッドでは、依然としてアクセス許可 A が必要です。

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 に対する確認要求を配置する例を次に示します。このコードは、コンストラクタに PermissionState.Unrestricted フラグを渡し、CustomPermission クラスの新しいインスタンスを作成します。その後に 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.
}
Noteメモ :

確認要求の最適の動作は、64 ビットと 32 ビットのプラットフォームで異なります。64 ビットのプラットフォームでは、他の呼び出し元アセンブリがない場合、確認要求が含まれるアセンブリの許可セットはチェックされません。ただし、呼び出し元アセンブリがある場合はスタック ウォークが実行されるため、この最適化によって特権の昇格は起こりません。32 ビットのプラットフォームでは、確認要求およびすべての呼び出し元アセンブリを含むアセンブリの許可セットがチェックされます。

参照

関連項目

SecurityException Class

概念

セキュリティ確認要求
独自のコード アクセス許可の作成
宣言セキュリティのサポートの追加
安全なクラス ライブラリの作成

その他の技術情報

属性を使用したメタデータの拡張
コード アクセス セキュリティ