Управление доступом для кода и 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. Разрешено ли выполнение этого кода или нет, зависит от источника кода или других аспектов происхождения кода, а не только идентификатора участника.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 Permissions

При выполнении кода он предоставляет свидетельство, которое проверяется системой безопасности CLR.When code is executed, it presents evidence that is evaluated by the CLR security system. Обычно это свидетельство состоит из источника кода, включая URL-адрес, узел и зону, а также цифровые сигнатуры, которые подтверждают происхождение сборки.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. Если начать с предоставления всех прав, а затем удалять отдельные их них, то приложение окажется небезопасным. В нем могут возникать неожиданные бреши в системе безопасности из-за предоставления больших прав доступа, чем необходимо.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.

Существует три типа прав доступа для кода.There are three types of code access permissions:

  • Code access permissions получаются из класса CodeAccessPermission.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. Права доступа для удостоверения также являются производными от базового класса CodeAccessPermission.Identity permissions also derive from the CodeAccessPermission base class.

  • Role-based security permissions основаны на том, имеет ли участник указанное свидетельство или является ли членом указанной роли.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. Если какой-либо вызывающий объект в стеке вызова не имеет запрашиваемого разрешения, формируется исключение 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 или пользовательских удостоверениях, которые предоставляют сведения об участнике безопасности текущему потоку.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. Права доступа на основе ролей предоставляют механизм для определения, имеет ли пользователь (или агент, действующий от имени пользователя) конкретное удостоверение или является ли он членом указанной роли.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

Строгое имя или цифровая сигнатура состоит из идентификатора сборки, в который входит ее простое текстовое имя, номер версии и сведения о языке и региональных настройках (если указано) плюс открытый ключ и цифровая сигнатура.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.

Строгое имя сборки дает приложению или компоненту уникальный идентификатор, который может использоваться другими программами явной ссылки на сборку.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. Сборки, которые будут установлены в глобальный кэш сборок, должны получать строгие имена.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.0Partial Trust in ADO.NET 2.0

Теперь в ADO.NET 2.0 поставщик данных .NET Framework для SQL Server, поставщик данных .NET Framework для OLE DB, поставщик данных .NET Framework для ODBC и поставщик данных .NET Framework для 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 в приложениях с неполным доверием поддерживался только клиент System.Data.SqlClient.In previous releases of the .NET Framework, only System.Data.SqlClient was supported in less than full-trust applications.

У частично доверенного приложения, использующего поставщик the SQL Server, как минимум, должно быть право доступа для выполнения и право доступа SqlClientPermission.At minimum, a partially trusted application using the SQL Server provider must have execution and SqlClientPermission permissions.

Свойства атрибута разрешения для частичного уровня доверияPermission Attribute Properties for Partial Trust

Чтобы еще сильнее ограничить возможности поставщика данных .NET Framework для SQL Server, в сценариях с частичным уровнем доверия можно использовать члены SqlClientPermissionAttribute.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. Примечание. Не включайте в строку соединения идентификатор пользователя или пароль.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.

Синтаксис ConnectionStringConnectionString 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>  

Синтаксис KeyRestrictionsKeyRestrictions Syntax

В следующем примере включается та же строка соединения, позволяет использовать Encrypt и Packet 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 с PreventUsageKeyRestrictionBehavior with PreventUsage Syntax

В следующем примере включается та же строка соединения и разрешается использование всех остальных параметров строки соединения, за исключением User Id, Password и 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 с AllowOnlyKeyRestrictionBehavior with AllowOnly Syntax

В следующем примере включаются две строки соединения, которые также содержат параметры Initial Catalog, Connection Timeout, Encrypt и Packet Size.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>  

Разрешение частичного уровня доверия при помощи пользовательских наборов прав доступа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, переименуйте его в «CustomLocalIntranet», добавить System.Data.SqlClient импортировать разрешения, набор прав доступа набор разрешений, используя Caspol.exe (средство политики безопасности доступа кода)и задать набор разрешений LocalIntranet_Zone в набор прав доступа.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 для 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 при помощи прав доступа Security PermissionsVerifying ADO.NET Code Access Using Security Permissions

В сценариях с частичным доверием для некоторых методов в коде можно затребовать права доступа CAS, указав SqlClientPermissionAttribute.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.

Важно!

При разработке прав доступа CAS для ADO.NET рекомендуется начинать с наиболее жестких ограничений (полное отсутствие прав доступа), а затем добавлять определенные права доступа, необходимые конкретной задаче, которую требуется выполнить коду.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 выполняет запрос на право доступа, который формирует исключение SecurityException при отсутствии соответствующих прав доступа CAS.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
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-компоненты можно встраивать в приложение .NET Framework, используя средства COM-взаимодействия для импорта соответствующих типов 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-компонента.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