コード アクセス セキュリティと ADO.NETCode Access Security and ADO.NET

.NET Framework はコード アクセス セキュリティ (CAS) に加えてロール ベースのセキュリティを備えています。どちらも、共通言語ランタイム (CLR) が提供する共通のインフラストラクチャを使って実装されています。The .NET Framework offers role-based security as well as code access security (CAS), both of which are implemented using a common infrastructure supplied by the common language runtime (CLR). アンマネージ コードの場合、ほとんどのアプリケーションはユーザーまたはプリンシパルの権限で実行されます。In the world of unmanaged code, most applications execute with the permissions of the user or principal. そのため、悪意のあるソフトウェアやエラーを含むソフトウェアが、システム特権を持つユーザーによって実行された場合、コンピューター システムが被害を受けたり、機密データが改ざんされる可能性があります。As a result, computer systems can be damaged and private data compromised when malicious or error-filled software is run by a user with elevated privileges.

これに対し、.NET Framework で実行されるマネージド コードには、コードそのものに適用されるコード アクセス セキュリティが存在します。By contrast, managed code executing in the .NET Framework includes code access security, which applies to code alone. コードの実行が許可されるかどうかは、プリンシパルの ID だけでなく、コードの作成元など、コードの ID を表す情報に依存します。Whether the code is allowed to run or not depends on the code's origin or other aspects of the code's identity, not solely the identity of the principal. これにより、マネージド コードが誤用される可能性が低くなります。This reduces the likelihood that managed code can be misused.

Code Access PermissionsCode Access Permissions

コードは、実行されるときに、CLR のセキュリティ システムで評価される証拠を提示します。When code is executed, it presents evidence that is evaluated by the CLR security system. 通常、この証拠は、URL、サイト、ゾーン、アセンブリの ID を保証するデジタル署名などのコードの作成元に関する情報で構成されます。Typically, this evidence comprises the origin of the code including URL, site, and zone, and digital signatures that ensure the identity of the assembly.

CLR は、そのコードに許されている操作の範囲内で実行を許可します。The CLR allows code to perform only those operations that the code has permission to perform. コードは権限を要求できますが、その要求は管理者が設定したセキュリティ ポリシーに基づいて受理されます。Code can request permissions, and those requests are honored based on the security policy set by an administrator.

注意

CLR で実行されるコード自体に、アクセス許可を与えることはできません。Code executing in the CLR cannot grant permissions to itself. たとえば、コードから要求できる権限は、セキュリティ ポリシーによって許可されたレベルよりも低い権限だけであり、それを超える権限が付与されることはありません。For example, code can request and be granted fewer permissions than a security policy allows, but it will never be granted more permissions. 権限を付与する場合は、まず、権限をまったく付与しない状態から始め、その後で、実行しようとする特定のタスクに必要な最小限の権限を追加してゆくようにします。When granting permissions, start with no permissions at all and then add the narrowest permissions for the particular task being performed. すべての権限を与えてから、不要なものを 1 つずつ拒否していく方法では、アプリケーションを危険にさらす結果となります。必要以上の権限を付与することによって意図しないセキュリティ ホールを招く可能性があります。Starting with all permissions and then denying individual ones leads to insecure applications that may contain unintentional security holes from granting more permissions than required. 詳細については、「セキュリティポリシーの構成」および「セキュリティポリシーの管理」を参照してください。For more information, see Configuring Security Policy and Security Policy Management.

コードのアクセス権限には、次の 3 種類があります。There are three types of code access permissions:

  • Code access permissionsCodeAccessPermission クラスから派生します。Code access permissions derive from the CodeAccessPermission class. ファイルや環境変数などの保護されたリソースにアクセスして、保護された操作 (アンマネージ コードへのアクセスなど) を実行するには権限が必要です。Permissions are required in order to access protected resources, such as files and environment variables, and to perform protected operations, such as accessing unmanaged code.

  • Identity permissions。アセンブリを識別する特性を表します。Identity permissions represent characteristics that identify an assembly. アセンブリには証拠に基づいて権限が付与されます。証拠には、デジタル署名やコードの作成元などの情報が含まれます。Permissions are granted to an assembly based on evidence, which can include items such as a digital signature or where the code originated. ID 権限も CodeAccessPermission 基本クラスから派生します。Identity permissions also derive from the CodeAccessPermission base class.

  • Role-based security permissions。プリンシパルが、指定された ID を持っているか、または、指定されたロールに属しているかどうかに基づきます。Role-based security permissions are based on whether a principal has a specified identity or is a member of a specified role. PrincipalPermission クラスにより、アクティブなプリンシパルに対する宣言型および命令型の権限チェックが可能となります。The PrincipalPermission class allows both declarative and imperative permission checks against the active principal.

ランタイムのセキュリティ システムは、特定のリソースへのアクセスまたは特定の操作の実行がコードに許されているかどうかを判断するため、呼び出し履歴をたどりながら、各呼び出し元に付与されている権限と、要求されている権限とを比較します。To determine whether code is authorized to access a resource or perform an operation, the runtime's security system traverses the call stack, comparing the granted permissions of each caller to the permission being demanded. 呼び出し履歴に、要求された権限を持たない呼び出し元が 1 つでも見つかった場合、SecurityException がスローされてアクセスが拒否されます。If any caller in the call stack does not have the demanded permission, a SecurityException is thrown and access is refused.

権限の要求Requesting Permissions

権限を要求する目的は、そのアプリケーションを実行するために必要な権限をランタイムに伝えると共に、実際に必要な権限以外は付与されないようにすることです。The purpose of requesting permissions is to inform the runtime which permissions your application requires in order to run, and to ensure that it receives only the permissions that it actually needs. たとえば、ローカル ディスクにデータを書き込むアプリケーションは FileIOPermission を必要とします。For example, if your application needs to write data to the local disk, it requires FileIOPermission. この権限が付与されていない場合、アプリケーションがディスクへの書き込みを試行した時点で実行に失敗します。If that permission hasn't been granted, the application will fail when it attempts to write to the disk. ただし、アプリケーションから FileIOPermission を要求した場合、その権限が付与されなければ、最初の段階で例外が生成され、アプリケーションが読み込まれることはありません。However, if the application requests FileIOPermission and that permission has not been granted, the application will generate the exception at the outset and will not load.

ディスクからのデータの読み取りだけを必要とするアプリケーションでは、書き込み権限が決して付与されないように要求できます。In a scenario where the application only needs to read data from the disk, you can request that it never be granted any write permissions. バグが存在していたり、悪意のある攻撃を受けたとしても、操作の対象となるデータに損害を与えることはありません。In the event of a bug or a malicious attack, your code cannot damage the data on which it operates. 詳細については、「アクセス許可の要求」を参照してください。For more information, see Requesting Permissions.

ロール ベースのセキュリティと CASRole-Based Security and CAS

ロール ベースのセキュリティとコード アクセス セキュリティ (CAS) の両方を実装することで、アプリケーションの全体的なセキュリティを高めることができます。Implementing both role-based security and code-accessed security (CAS) enhances overall security for your application. ロール ベースのセキュリティには、Windows アカウントまたはカスタム ID を使用できます。セキュリティ プリンシパルに関する情報には、現在のスレッドからアクセスできます。Role-based security can be based on a Windows account or a custom identity, making information about the security principal available to the current thread. また、ユーザーによって指定された資格情報に基づいて、データやリソースへのアクセスを提供するアプリケーションも少なくありません。In addition, applications are often required to provide access to data or resources based on credentials supplied by the user. このようなアプリケーションは、通常、ユーザーのロールを調べ、そのロールに基づいてリソースへのアクセスを許可します。Typically, such applications check the role of a user and provide access to resources based on those roles.

ロール ベースのセキュリティを使用することで、コンポーネントが、現在のユーザーおよびそのユーザーに関連付けられているロールを実行時に特定できるようになります。Role-based security enables a component to identify current users and their associated roles at run time. この情報を CAS ポリシーを使ってマッピングすることによって、一連の権限が実行時に判別されます。This information is then mapped using a CAS policy to determine the set of permissions granted at run time. 特定のアプリケーション ドメインでは、ホストが既定のロール ベース セキュリティ ポリシーを変更し、ユーザーおよびそのユーザーに関連付けられたロールを表す既定のセキュリティ プリンシパルを設定できます。For a specified application domain, the host can change the default role-based security policy and set a default security principal that represents a user and the roles associated with that user.

CLR にはマネージド コードに制限を適用するためのメカニズムが、権限を使用することによって実装されています。The CLR uses permissions to implement its mechanism for enforcing restrictions on managed code. ロール ベースのセキュリティ権限により、ユーザー (またはユーザーのために行動するエージェント) が特定の ID を持っているかどうか、または特定のロールに所属しているかどうかを検出するメカニズムが実現されます。Role-based security permissions provide a mechanism for discovering whether a user (or the agent acting on the user's behalf) has a particular identity or is a member of a specified role. 詳細については、「セキュリティのアクセス許可」を参照してください。For more information, see Security Permissions.

開発しているアプリケーションの種類によっては、データベースに対するロール ベースの権限の実装も考慮する必要があります。Depending on the type of application you are building, you should also consider implementing role-based permissions in the database. SQL Server のロールベースセキュリティの詳細については、「 SQL Server セキュリティ」を参照してください。For more information on role-based security in SQL Server, see SQL Server Security.

アセンブリAssemblies

アセンブリは、.NET Framework アプリケーションの配置、バージョン管理、再利用、アクティベーション スコープ、およびセキュリティ権限の基本単位です。Assemblies form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions for a .NET Framework application. アセンブリは、互いに連携して動作するように作成された一連の型やリソースを提供し、"機能" の論理上の単位を成すものです。An assembly provides a collection of types and resources that are built to work together and form a logical unit of functionality. CLR から見て、型がアセンブリのコンテキスト外に存在することはありません。To the CLR, a type does not exist outside the context of an assembly. アセンブリの作成と配置の詳細については、「アセンブリを使用したプログラミング」を参照してください。For more information on creating and deploying assemblies, see Programming with Assemblies.

厳密な名前付きアセンブリStrong-naming Assemblies

厳密な名前 (デジタル署名) は、アセンブリの ID (単純なテキスト名、バージョン番号、および使用可能な場合はカルチャ情報) と、公開キーおよびデジタル署名で構成されます。A strong name, or digital signature, consists of the assembly's identity, which includes its simple text name, version number, and culture information (if provided), plus a public key and a digital signature. このデジタル署名は、対応する秘密キーを使用してアセンブリ ファイルから生成されます。The digital signature is generated from an assembly file using the corresponding private key. アセンブリ ファイルにはアセンブリ マニフェストが格納されており、そこに、アセンブリを構成するすべてのファイルの名前とハッシュが含まれます。The assembly file contains the assembly manifest, which contains the names and hashes of all the files that make up the assembly.

アセンブリに厳密な名前を付けることで、アプリケーションやコンポーネントに一意の ID が与えられます。他のソフトウェアは、その ID を使用することで、対応するアプリケーションまたはコンポーネントを明示的に参照できます。Strong naming an assembly gives an application or component a unique identity that other software can use to refer explicitly to it. アセンブリに厳密な名前を付けると、悪意のあるコードを含むアセンブリのなりすましから保護することができます。Strong naming guards assemblies against being spoofed by an assembly that contains hostile code. また、異なるバージョンのコンポーネント間でバージョンの整合性をとることもできます。Strong-naming also ensures versioning consistency among different versions of a component. グローバル アセンブリ キャッシュ (GAC) に展開されるアセンブリには、厳密な名前を付ける必要があります。You must strong name assemblies that will be deployed to the Global Assembly Cache (GAC). 詳しくは、「厳密な名前付きアセンブリの作成と使用」をご覧ください。For more information, see Creating and Using Strong-Named Assemblies.

ADO.NET 2.0 での Partial Trust (部分信頼)Partial Trust in ADO.NET 2.0

ADO.NET 2.0 では、.NET Framework Data Provider for SQL Server、.NET Framework Data Provider for OLE DB、.NET Framework Data Provider for ODBC、および .NET Framework Data Provider for Oracle のすべてが、部分的に信頼された環境でも実行できるようになりました。In ADO.NET 2.0, the .NET Framework Data Provider for SQL Server, the .NET Framework Data Provider for OLE DB, the .NET Framework Data Provider for ODBC, and the .NET Framework Data Provider for Oracle can now all run in partially trusted environments. .NET Framework の以前のリリースでは、信頼性のレベルが full-trust よりも低いアプリケーションでは System.Data.SqlClient のみがサポートされていました。In previous releases of the .NET Framework, only System.Data.SqlClient was supported in less than full-trust applications.

SQL Server プロバイダーを使用する部分的に信頼できるアプリケーションは、少なくとも、Execution アクセス許可と SqlClientPermission アクセス許可が必要です。At minimum, a partially trusted application using the SQL Server provider must have execution and SqlClientPermission permissions.

Partial Trust (部分信頼) のアクセス許可属性プロパティPermission Attribute Properties for Partial Trust

部分信頼のシナリオでは、SqlClientPermissionAttribute メンバーを使用して、.NET Framework Data Provider for SQL Server が使用できる機能をさらに制限することができます。For partial trust scenarios, you can use SqlClientPermissionAttribute members to further restrict the capabilities available for the .NET Framework Data Provider for SQL Server.

使用可能な SqlClientPermissionAttribute プロパティとその説明を次の表に示します。The following table lists the available SqlClientPermissionAttribute properties and their descriptions:

アクセス許可属性プロパティPermission attribute property 説明Description
Action セキュリティ アクションを取得または設定します。Gets or sets a security action. このプロパティは、SecurityAttribute から継承されています。Inherited from SecurityAttribute.
AllowBlankPassword 接続文字列内で空白のパスワードの使用を許可または禁止します。Enables or disables the use of a blank password in a connection string. 有効な値は、空白のパスワードの使用を許可する true および空白のパスワードの使用を禁止する false です。Valid values are true (to enable the use of blank passwords) and false (to disable the use of blank passwords). このプロパティは、DBDataPermissionAttribute から継承されています。Inherited from DBDataPermissionAttribute.
ConnectionString 使用できる接続文字列を指定します。Identifies a permitted connection string. 複数の接続文字列を指定できます。Multiple connection strings can be identified. 注: 接続文字列には、ユーザー ID やパスワードを含めないでください。Note: Do not include a user ID or password in your connection string. このリリースでは、.NET Framework 構成ツールを使用して接続文字列制限を変更することはできません。In this release, you cannot change connection string restrictions using the .NET Framework Configuration Tool.

このプロパティは、DBDataPermissionAttribute から継承されています。Inherited from DBDataPermissionAttribute.
KeyRestrictions 許可または禁止する接続文字列パラメーターを指定します。Identifies connection string parameters that are allowed or disallowed. 接続文字列パラメーターが、フォームで識別される <パラメーター名>= します。Connection string parameters are identified in the form <parameter name>=. セミコロン (;) で区切って、複数のパラメーターを指定できます。Multiple parameters can be specified, delimited using a semicolon (;). 注: KeyRestrictions が指定されておらず、KeyRestrictionBehavior プロパティが AllowOnly または PreventUsage に設定されている場合は、接続文字列パラメーターを追加できません。Note: If you do not specify KeyRestrictions, but you set KeyRestrictionBehavior property to AllowOnly or PreventUsage, no additional connection string parameters are allowed. このプロパティは、DBDataPermissionAttribute から継承されています。Inherited from DBDataPermissionAttribute.
KeyRestrictionBehavior 接続文字列パラメーターが、追加を許可された唯一の接続文字列パラメーター (AllowOnly) か、または追加を禁止された接続文字列パラメーター (PreventUsage) かを指定します。Identifies the connection string parameters as the only additional parameters allowed (AllowOnly), or identifies the additional parameters that are not allowed (PreventUsage). AllowOnly が既定値です。AllowOnly is the default. このプロパティは、DBDataPermissionAttribute から継承されています。Inherited from DBDataPermissionAttribute.
TypeID 派生クラスで実装すると、この属性の一意の識別子を取得します。Gets a unique identifier for this attribute when implemented in a derived class. このプロパティは、Attribute から継承されています。Inherited from Attribute.
Unrestricted このリソースに対する無制限のアクセス許可が宣言されているかどうかを示します。Indicates whether unrestricted permission to the resource is declared. このプロパティは、SecurityAttribute から継承されています。Inherited from SecurityAttribute.

ConnectionString の構文ConnectionString Syntax

次の例では、特定の接続文字列のみ使用できるようにするために、構成ファイルの connectionStrings 要素を使用する方法を示しています。The following example demonstrates how to use the connectionStrings element of a configuration file to allow only a specific connection string to be used. 構成ファイルからの接続文字列の格納と取得の詳細については、「接続文字列」を参照してください。See Connection Strings for more information on storing and retrieving connection strings from configuration files.

<connectionStrings>  
  <add name="DatabaseConnection"   
    connectionString="Data Source=(local);Initial   
    Catalog=Northwind;Integrated Security=true;" />  
</connectionStrings>  

KeyRestrictions の構文KeyRestrictions Syntax

次の例では、同じ接続文字列を有効にし、 EncryptPacket Sizeの接続文字列オプションを使用できるようにしますが、その他の接続文字列オプションの使用は制限します。The following example enables the same connection string, enables the use of the Encrypt and Packet Size connection string options, but restricts the use of any other connection string options.

<connectionStrings>  
  <add name="DatabaseConnection"   
    connectionString="Data Source=(local);Initial   
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="Encrypt=;Packet Size=;"  
    KeyRestrictionBehavior="AllowOnly" />  
</connectionStrings>  

KeyRestrictionBehavior を PreventUsage に設定する場合の構文KeyRestrictionBehavior with PreventUsage Syntax

上述の接続文字列の使用を許可し、User IdPassword、および Persist Security Info を除く他のすべての接続パラメーターを許可する例を次に示します。The following example enables the same connection string and allows all other connection parameters except for User Id, Password and Persist Security Info.

<connectionStrings>  
  <add name="DatabaseConnection"   
    connectionString="Data Source=(local);Initial   
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="User Id=;Password=;Persist Security Info=;"  
    KeyRestrictionBehavior="PreventUsage" />  
</connectionStrings>  

KeyRestrictionBehavior を AllowOnly に設定する場合の構文KeyRestrictionBehavior with AllowOnly Syntax

Initial CatalogConnection TimeoutEncrypt、および Packet Size パラメーターも含まれる 2 つの接続文字列の使用を許可する例を次に示します。The following example enables two connection strings that also contain Initial Catalog, Connection Timeout, Encrypt, and Packet Size parameters. その他の接続文字列パラメーターは、すべて制限されます。All other connection string parameters are restricted.

<connectionStrings>  
  <add name="DatabaseConnection"   
    connectionString="Data Source=(local);Initial   
    Catalog=Northwind;Integrated Security=true;"  
    KeyRestrictions="Initial Catalog;Connection Timeout=;  
       Encrypt=;Packet Size=;"   
    KeyRestrictionBehavior="AllowOnly" />  
  
  <add name="DatabaseConnection2"   
    connectionString="Data Source=SqlServer2;Initial   
    Catalog=Northwind2;Integrated Security=true;"  
    KeyRestrictions="Initial Catalog;Connection Timeout=;  
       Encrypt=;Packet Size=;"   
    KeyRestrictionBehavior="AllowOnly" />  
</connectionStrings>  

カスタム アクセス許可セットを使用した Partial Trust の有効化Enabling Partial Trust with a Custom Permission Set

特定のゾーンに対して System.Data.SqlClient アクセス許可を有効にするには、システム管理者がカスタム アクセス許可セットを作成して、目的のゾーンに指定する必要があります。To enable the use of System.Data.SqlClient permissions for a particular zone, a system administrator must create a custom permission set and set it as the permission set for a particular zone. LocalIntranet などの既定のアクセス許可セットは変更できません。Default permission sets, such as LocalIntranet, cannot be modified. たとえば、がであるSystem.Data.SqlClientコードZone LocalIntranetに対するアクセス許可を含めるには、システム管理者がのLocalIntranetアクセス許可セットをコピー System.Data.SqlClientし、その名前を "customlocalintranet" に変更し、アクセス許可を追加し、インポートします。caspol.exe (コードアクセスセキュリティポリシーツール)を使用して customlocalintranet アクセス許可セットを設定し、のLocalIntranet_Zoneアクセス許可セットを customlocalintranet に設定します。For example, to include System.Data.SqlClient permissions for code that has a Zone of LocalIntranet, a system administrator could copy the permission set for LocalIntranet, rename it to "CustomLocalIntranet", add the System.Data.SqlClient permissions, import the CustomLocalIntranet permission set using the Caspol.exe (Code Access Security Policy Tool), and set the permission set of LocalIntranet_Zone to CustomLocalIntranet.

サンプル アクセス許可セットSample Permission Set

部分信頼のシナリオでの、.NET Framework Data Provider for SQL Server 用アクセス許可セットの例を次に示します。The following is a sample permission set for the .NET Framework Data Provider for SQL Server in a partially trusted scenario. カスタムアクセス許可セットの作成の詳細については、「 Caspol.exe を使用したアクセス許可セットの構成」を参照してください。For information on creating custom permission sets, see Configuring Permission Sets Using Caspol.exe.

<PermissionSet class="System.Security.NamedPermissionSet"  
  version="1"  
  Name="CustomLocalIntranet"  
  Description="Custom permission set given to applications on  
    the local intranet">  
  
<IPermission class="System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"  
version="1"  
AllowBlankPassword="False">  
<add ConnectionString="Data Source=(local);Integrated Security=true;"  
 KeyRestrictions="Initial Catalog=;Connection Timeout=;  
   Encrypt=;Packet Size=;"   
 KeyRestrictionBehavior="AllowOnly" />  
 </IPermission>  
</PermissionSet>  

セキュリティ アクセス許可を使用した ADO.NET コード アクセスの検証Verifying ADO.NET Code Access Using Security Permissions

部分信頼のシナリオでは、SqlClientPermissionAttribute を指定することによって、コード内の特定のメソッドに対する CAS 特権を要求できます。For partial-trust scenarios, you can require CAS privileges for particular methods in your code by specifying a SqlClientPermissionAttribute. 制限されたセキュリティ ポリシーによって、実際にはその特権が許可されていない場合は、そのコードを実行する前に例外がスローされます。If that privilege is not allowed by the restricted security policy in effect, an exception is thrown before your code is run. セキュリティポリシーの詳細については、「セキュリティポリシーの管理セキュリティポリシーのベストプラクティス」を参照してください。For more information on security policy, see Security Policy Management and Security Policy Best Practices.

Example

次のサンプルは、特定の接続文字列を必要とするコードの作成方法を示しています。The following example demonstrates how to write code that requires a particular connection string. このサンプルは、System.Data.SqlClient に対する無制限の権限を拒否する機能をシミュレートします。この機能は、実際には、システム管理者が、CAS ポリシーを使用して実装します。It simulates denying unrestricted permissions to System.Data.SqlClient, which a system administrator would implement using a CAS policy in the real world.

重要

ADO.NET の CAS 権限を定義する場合、最も制限の厳しいケース (権限なし) から開始し、その後で、コードが実行する特定のタスクに必要な特定の権限を追加するというのが、適切なパターンです。When designing CAS permissions for ADO.NET, the correct pattern is to start with the most restrictive case (no permissions at all) and then add the specific permissions that are needed for the particular task that the code needs to perform. 逆に、すべての権限を与えてから特定の権限を拒否してゆく方法は、安全ではありません。同じ接続文字列を表現する方法が多数あるためです。The opposite pattern, starting with all permissions and then denying a specific permission, is not secure because there are many ways of expressing the same connection string. たとえば、すべての権限を与えた後で接続文字列 "server=someserver" の使用を拒否しても、"server=someserver.mycompany.com" という接続文字列は使用可能です。For example, if you start with all permissions and then attempt to deny the use of the connection string "server=someserver", the string "server=someserver.mycompany.com" would still be allowed. 常に権限をまったく与えない状態から開始することで、権限セットのセキュリティ ホールを減らすことができます。By always starting by granting no permissions at all, you reduce the chances that there are holes in the permission set.

SqlClient でセキュリティ確認要求を実行する方法を、次のコードに示します。CAS の権限が適切に設定されていない場合、SecurityException がスローされます。The following code demonstrates how SqlClient performs the security demand, which throws a SecurityException if the appropriate CAS permissions are not in place. SecurityException の出力は、コンソール ウィンドウに表示されます。The SecurityException output is displayed in the console window.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Security;
using System.Security.Permissions;
 
namespace PartialTrustTopic {
   public class PartialTrustHelper : MarshalByRefObject {
      public void TestConnectionOpen(string connectionString) {
         // Try to open a connection.
         using (SqlConnection connection = new SqlConnection(connectionString)) {
            connection.Open();
         }
      }
   }
 
   class Program {
      static void Main(string[] args) {
         TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated Security=true;Initial Catalog=Test");
      }
 
      static void TestCAS(string connectString1, string connectString2) {
         // Create permission set for sandbox AppDomain.
         // This example only allows execution.
         PermissionSet permissions = new PermissionSet(PermissionState.None);
         permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
 
         // Create sandbox AppDomain with permission set that only allows execution,
         // and has no SqlClientPermissions.
         AppDomainSetup appDomainSetup = new AppDomainSetup();
         appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
         AppDomain firstDomain = AppDomain.CreateDomain("NoSqlPermissions", null, appDomainSetup, permissions);
 
         // Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
         Type helperType = typeof(PartialTrustHelper);
         PartialTrustHelper firstHelper = (PartialTrustHelper)firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);
 
         try {
            // Attempt to open a connection in the sandbox AppDomain.
            // This is expected to fail.
            firstHelper.TestConnectionOpen(connectString1);
            Console.WriteLine("Connection opened, unexpected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Failed, as expected: {0}",
                ex.FirstPermissionThatFailed);
 
            // Uncomment the following line to see Exception details.
            // Console.WriteLine("BaseException: " + ex.GetBaseException());
         }
 
         // Add permission for a specific connection string.
         SqlClientPermission sqlPermission = new SqlClientPermission(PermissionState.None);
         sqlPermission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly);
 
         permissions.AddPermission(sqlPermission);
 
         AppDomain secondDomain = AppDomain.CreateDomain("OneSqlPermission", null, appDomainSetup, permissions);
         PartialTrustHelper secondHelper = (PartialTrustHelper)secondDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName);
 
         // Try connection open again, it should succeed now.
         try {
            secondHelper.TestConnectionOpen(connectString1);
            Console.WriteLine("Connection opened, as expected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Unexpected failure: {0}", ex.Message);
         }
 
         // Try a different connection string. This should fail.
         try {
            secondHelper.TestConnectionOpen(connectString2);
            Console.WriteLine("Connection opened, unexpected.");
         }
         catch (System.Security.SecurityException ex) {
            Console.WriteLine("Failed, as expected: {0}", ex.Message);
         }
      }
   }
}
Imports System.Data
Imports System.Data.SqlClient
Imports System.Security
Imports System.Security.Permissions

Namespace PartialTrustTopic
   Public Class PartialTrustHelper
      Inherits MarshalByRefObject
      Public Sub TestConnectionOpen(ByVal connectionString As String)
         ' Try to open a connection.
         Using connection As New SqlConnection(connectionString)
            connection.Open()
         End Using
      End Sub
   End Class

   Class Program
      Public Shared Sub Main(ByVal args As String())
         TestCAS("Data Source=(local);Integrated Security=true", "Data Source=(local);Integrated Security=true;Initial Catalog=Test")
      End Sub

      Public Shared Sub TestCAS(ByVal connectString1 As String, ByVal connectString2 As String)
         ' Create permission set for sandbox AppDomain.
         ' This example only allows execution.
         Dim permissions As New PermissionSet(PermissionState.None)
         permissions.AddPermission(New SecurityPermission(SecurityPermissionFlag.Execution))

         ' Create sandbox AppDomain with permission set that only allows execution,
         ' and has no SqlClientPermissions.
         Dim appDomainSetup As New AppDomainSetup()
         appDomainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
         Dim firstDomain As AppDomain = AppDomain.CreateDomain("NoSqlPermissions", Nothing, appDomainSetup, permissions)

         ' Create helper object in sandbox AppDomain so that code can be executed in that AppDomain.
         Dim helperType As Type = GetType(PartialTrustHelper)
         Dim firstHelper As PartialTrustHelper = DirectCast(firstDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName), PartialTrustHelper)

         Try
            ' Attempt to open a connection in the sandbox AppDomain.
            ' This is expected to fail.
            firstHelper.TestConnectionOpen(connectString1)
            Console.WriteLine("Connection opened, unexpected.")
         Catch ex As System.Security.SecurityException

            ' Uncomment the following line to see Exception details.
            ' Console.WriteLine("BaseException: " + ex.GetBaseException());
            Console.WriteLine("Failed, as expected: {0}", ex.FirstPermissionThatFailed)
         End Try

         ' Add permission for a specific connection string.
         Dim sqlPermission As New SqlClientPermission(PermissionState.None)
         sqlPermission.Add(connectString1, "", KeyRestrictionBehavior.AllowOnly)

         permissions.AddPermission(sqlPermission)

         Dim secondDomain As AppDomain = AppDomain.CreateDomain("OneSqlPermission", Nothing, appDomainSetup, permissions)
         Dim secondHelper As PartialTrustHelper = DirectCast(secondDomain.CreateInstanceAndUnwrap(helperType.Assembly.FullName, helperType.FullName), PartialTrustHelper)

         ' Try connection open again, it should succeed now.
         Try
            secondHelper.TestConnectionOpen(connectString1)
            Console.WriteLine("Connection opened, as expected.")
         Catch ex As System.Security.SecurityException
            Console.WriteLine("Unexpected failure: {0}", ex.Message)
         End Try

         ' Try a different connection string. This should fail.
         Try
            secondHelper.TestConnectionOpen(connectString2)
            Console.WriteLine("Connection opened, unexpected.")
         Catch ex As System.Security.SecurityException
            Console.WriteLine("Failed, as expected: {0}", ex.Message)
         End Try
      End Sub
   End Class
End Namespace

コンソール ウィンドウに表示される出力の例を次に示します。You should see this output in the Console window:

Failed, as expected: <IPermission class="System.Data.SqlClient.  
SqlClientPermission, System.Data, Version=2.0.0.0,   
  Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1"  
  AllowBlankPassword="False">  
<add ConnectionString="Data Source=(local);Initial Catalog=  
  Northwind;Integrated Security=SSPI" KeyRestrictions=""  
KeyRestrictionBehavior="AllowOnly"/>  
</IPermission>  
  
Connection opened, as expected.  
Failed, as expected: Request failed.  

アンマネージ コードとの相互運用性Interoperability with Unmanaged Code

CLR の外部で実行されるコードはアンマネージ コードと呼ばれます。Code that runs outside the CLR is called unmanaged code. したがって、CAS などのセキュリティ メカニズムをアンマネージ コードに適用することはできません。Therefore, security mechanisms such as CAS cannot be applied to unmanaged code. アンマネージ コードの例としては、COM コンポーネント、ActiveX インターフェイス、Windows API 関数があります。COM components, ActiveX interfaces, and Windows API functions are examples of unmanaged code. アンマネージ コードを実行する場合は、アプリケーションの全体的なセキュリティが損なわれないよう特別な考慮をする必要があります。Special security considerations apply when executing unmanaged code so that you do not jeopardize overall application security. 詳細については、「アンマネージ コードとの相互運用」を参照してください。For more information, see Interoperating with Unmanaged Code.

.NET Framework は、COM 相互運用機能を介したアクセスを提供することによって、既存の COM コンポーネントとの下位互換性をサポートしています。The .NET Framework also supports backward compatibility to existing COM components by providing access through COM interop. COM 相互運用ツールを使って適切な COM 型をインポートすることにより、.NET Framework アプリケーションに COM コンポーネントを組み込むことができます。You can incorporate COM components into a .NET Framework application by using COM interop tools to import the relevant COM types. インポートが完了すると、COM 型を使用できるようになります。Once imported, the COM types are ready to use. アセンブリのメタデータをタイプ ライブラリにエクスポートし、マネージド コンポーネントを COM コンポーネントとして登録することで、COM クライアントからマネージド コードにアクセスすることもできます。COM interop also enables COM clients to access managed code by exporting assembly metadata to a type library and registering the managed component as a COM component. 詳細については、「高度な COM 相互運用性」を参照してください。For more information, see Advanced COM Interoperability.

関連項目See also