次の方法で共有


Deny

Deny を呼び出すことによって、その呼び出しで拒否されたアクセス許可によって指定されているリソースへのアクセスを防止できます。コードで Deny を呼び出した後に、それによって拒否されたアクセス許可を下位の呼び出し元が要求すると、すべての呼び出し元が該当するリソースへのアクセス許可を持っている場合でも、セキュリティ チェックは失敗します。要求されるアクセス許可と拒否されるアクセス許可が正確に一致しなくても、Deny は有効に機能します。また、要求されるアクセス許可が拒否されるアクセス許可のサブセットである必要もありません。ただし、これら 2 つのアクセス許可の積集合が空の場合 (つまり両方に共通のアクセス許可が存在しない場合) は、Deny の呼び出しは無効になります。Deny は、Assert を実行するコール スタック上でさらに深い位置にあるコードをオーバーライドすることはできません。コール スタック上でさらに深い位置にあるコードが Assert を実行する場合、そのコードは、コール スタックの上位のコードが拒否するリソースにアクセスできます。

コード内で Deny を呼び出すと、Deny によって拒否されたリソースにアクセスするためにそのコードを利用することはできなくなるため、開発者はコードの悪用などに関して責任を回避できます。しかし、Deny を呼び出しても、下位の呼び出し元がその後で実行するセキュリティ アサーションは防止できません。

Deny を使用した場合に実行される処理を次の図に示します。この図では、アセンブリ A、B、C、D、E、およびアクセス許可 P1 について、次のことが当てはまります。

  • P1 は、C ドライブ上のすべてのファイルを読み取る権限を表しています。
  • アセンブリ A、B、C、D、E はアクセス許可 P1 を与えられています。
  • メソッド F は、アクセス許可 P1 に対する確認要求を行います。
  • メソッド C は P1 クラスのインスタンスを作成し、P1 の Deny メソッドを呼び出します。
  • メソッド A はアセンブリ A に含まれており、メソッド B はアセンブリ B に含まれています。メソッド C 以下も同様です。

Deny の使い方

メソッド C による Deny の呼び出しは、P1 に対する確認要求の結果に影響を与える可能性があります。たとえば、メソッド A が B を呼び出し、B が C を呼び出し、C が E を呼び出し、E が F を呼び出すとします。メソッド F は、P1 によって保護されているリソースに直接アクセスするため、P1 の Demand メソッドを呼び出す (または宣言的な確認要求を使用する) ことにより、P1 に対するセキュリティ チェックを実行します。この確認要求により、コール スタック内のすべての呼び出し元のアクセス許可について、アセンブリ E から順にチェックが実行されます。アセンブリ E はアクセス許可 P1 を与えられているため、次にアセンブリ C のアクセス許可がチェックされます。しかし、メソッド C は P1 を拒否しているため、メソッド E によって開始されたセキュリティ チェックはここで失敗し、SecurityException がスローされます。このセキュリティ チェックは、アセンブリ C とその呼び出し元 (アセンブリ A およびアセンブリ B) が P1 を与えられているかどうかには関係なく、必ず失敗します。メソッド C が Deny を呼び出したため、アセンブリ A およびアセンブリ B のコードも、P1 によって保護されているリソースにアクセスできなくなります。

Deny メソッドを使用してセキュリティ チェックをオーバーライドするための宣言構文の例を次のコードに示します。この例では、ReflectionPermission 構文は、SecurityAction 列挙と TypeInformation プロパティの設定の 2 つの値を指定します。TypeInformation は true に設定されているため、このアクセス許可にはリフレクションをとおしてプライベート メンバを見る権限があることを表しており、SecurityAction.Deny を渡してそのアクセス許可を拒否します。指定できるすべて値の一覧については、ReflectionPermission の説明を参照してください。このセキュリティ宣言によって、メソッドはリフレクションを通じて型のプライベート メンバを読み取ることができません。

Option Strict
Option Explicit
Imports System
Imports System.Security.Permissions
<ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true ")> Public Class 
MyClass1
   Public Sub New()
   End Sub
   Public Sub GetPublicMembers ()
      ' Access public members through reflection.
   End Sub
End Class
[C#]
using System;
using System.Security.Permissions;

[ReflectionPermissionAttribute(SecurityAction.Deny, TypeInformation = true)]
public class MyClass
{
   public MyClass()
   {    
   }   

   public void GetPublicMembers()
   {
      //Access public members through reflection.
   }  
}

Deny メソッドを使用してセキュリティ チェックをオーバーライドするための強制構文の例を次のコードに示します。この例では、ReflectionPermission オブジェクトが宣言され、そのコンストラクタには、現在のアクセス許可を初期化するために ReflectionPermissionFlag.TypeInformation が渡されます。Deny メソッドが呼び出されると、コードおよび呼び出し元は、リフレクションを通じてプライベート フィールドを読み取るのに使用できなくなります。

Option Explicit
Option Strict
Imports System
Imports System.Security.Permissions
Public Class MyClass1
   Public Sub New()
   End Sub
   Public Sub ReadRegistry()
      Dim MyPermission As New ReflectionPermission (ReflectionPermissionFlag.TypeInformation)
      MyPermission.Deny()
      ' Access public members through reflection.
   End Sub 
End Class
[C#]
using System;
using System.Security.Permissions;

public class MyClass {
   public MyClass() {    
   }   

   public void ReadRegistry() { 
      ReflectionPermission MyPermission = new ReflectionPermission (ReflectionPermissionFlag.TypeInformation);
      MyPermission.Deny();

      // Access public members through reflection.
   }  
}

Deny の使用による標準化の問題

単一のファイル、レジストリ エントリ、URL およびシステム パスは複数の名前を使用して記述できるため、FileIOPermissionRegistryPermissionWebPermissionUrlIdentityPermissionSiteIdentityPermission、および EnvironmentPermission を拒否する場合は特に入念な注意が必要です。たとえば、MyFile.log というファイルは、"c:\MyFile.log" や "\\MyMachineName\c$\MyFile.log" など、複数の方法で参照できます。"c:\MyFile.log" へのアクセスを表すアクセス許可を作成し、あるコードに対してこのアクセス許可を拒否した場合でも、代替パス "\\MyMachineName\c$\MyFile.log" を使用すると、このコードはファイルにアクセスできます。

標準化の問題を避けるには、PermitOnlyDeny を組み合わせて使用します。PermitOnly を使用すると、あるリソースに対して複数のアクセスの可能性がある名前の中から 1 つだけを指定でき、それ以外の別の名前を使ったそのリソースへのアクセスを拒否できます。PermitOnly を使用して、リソースへのアクセスを許可される名前を 1 つ指定した後、Deny を使用して、その名前でそのリソースへアクセスするのを禁止するようにします。

DenyPermitOnly の組み合わせを使用して、コードを MyLog.log. というリソースにアクセスさせないようにするコードを次に示します。また、このコードは代替名や代替パスを使用したリソースへのアクセスもブロックします。

<FileIOPermissionAttribute(SecurityAction.PermitOnly, All := "C:\ "), FileIOPermissionAttribute(SecurityAction.Deny, All := "C:\MyLog.log")>
[C#]
[FileIOPermissionAttribute(SecurityAction.PermitOnly, All = @"C:\ ")]
[FileIOPermissionAttribute(SecurityAction.Deny, All = @"C:\MyLog.log")] 

参照

属性を使用したメタデータの拡張 | セキュリティ チェックのオーバーライド | コード アクセス セキュリティ | SecurityAction 列挙体 | RegistryPermissionAttribute クラス