Seguridad de acceso del código y ADO.NETCode Access Security and ADO.NET

.NET Framework ofrece seguridad basada en roles y seguridad de acceso del código (CAS); ambas se implementan utilizando una infraestructura común proporcionada por Common Language Runtime (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). En el mundo del código no administrado, la mayoría de las aplicaciones se ejecutan mediante los permisos del usuario o de la entidad de seguridad.In the world of unmanaged code, most applications execute with the permissions of the user or principal. Por consiguiente, los sistemas de equipos pueden resultar dañados y se pueden poner en peligro los datos privados si un usuario con un nivel elevado de privilegios ejecuta software malintencionado o que contenga errores.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.

El código administrado que se ejecuta en .NET Framework, sin embargo, incluye seguridad de acceso del código, que se aplica únicamente al código.By contrast, managed code executing in the .NET Framework includes code access security, which applies to code alone. El permiso para que el código se ejecute o no depende de su origen o de otros aspectos de la identidad del código, y no solo de la identidad de la entidad de seguridad.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. De esta forma, se reduce la probabilidad de que se utilice el código de manera incorrecta.This reduces the likelihood that managed code can be misused.

Permisos de acceso del códigoCode Access Permissions

Cuando se ejecuta el código, éste presenta evidencia de que lo evalúa el sistema de seguridad Common Language Runtime CLR.When code is executed, it presents evidence that is evaluated by the CLR security system. Este tipo de evidencia normalmente contiene el origen del código, incluidos la dirección URL, el sitio, la zona y las firmas digitales que determinan la identidad del ensamblado.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 permite que el código realice únicamente las operaciones para las que tiene permiso.The CLR allows code to perform only those operations that the code has permission to perform. El código puede solicitar permisos y las peticiones se aceptan en función de la directiva de seguridad que haya establecido un administrador.Code can request permissions, and those requests are honored based on the security policy set by an administrator.

Nota

El código que se ejecuta en el CLR no se puede conceder permisos a sí mismo.Code executing in the CLR cannot grant permissions to itself. Por ejemplo, el código puede solicitar y que se le asignen menos permisos de los que concede una directiva de seguridad, pero no se le concederán más permisos.For example, code can request and be granted fewer permissions than a security policy allows, but it will never be granted more permissions. A la hora de conceder permisos, comience sin ningún permiso y agregue los mínimos permisos necesarios para la tarea concreta que se lleva a cabo.When granting permissions, start with no permissions at all and then add the narrowest permissions for the particular task being performed. Si se comienza con todos los permisos y posteriormente se deniegan permisos de forma individual, se obtienen aplicaciones poco seguras que pueden contener vulnerabilidades de seguridad no intencionadas debido a la concesión de más permisos de los que son necesarios.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. Para obtener más información, consulte configuración de directivas de seguridad y administración de directivas de seguridad.For more information, see Configuring Security Policy and Security Policy Management.

Hay tres tipos de permisos de acceso a código:There are three types of code access permissions:

  • Los Code access permissions derivan de la clase CodeAccessPermission.Code access permissions derive from the CodeAccessPermission class. Se requieren permisos para tener acceso a recursos protegidos, como archivos y variables de entorno, y para realizar operaciones protegidas, como el acceso a código no administrado.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.

  • Los Identity permissions representan características que identifican un ensamblado.Identity permissions represent characteristics that identify an assembly. Los permisos se conceden al ensamblado en función de la evidencia, que puede incluir elementos como una firma digital o el origen del código.Permissions are granted to an assembly based on evidence, which can include items such as a digital signature or where the code originated. Los permisos de identidad también derivan de la clase base CodeAccessPermission.Identity permissions also derive from the CodeAccessPermission base class.

  • Los Role-based security permissions se basan en el hecho de si una entidad de seguridad tiene una identidad especificada o si es miembro de una función especificada.Role-based security permissions are based on whether a principal has a specified identity or is a member of a specified role. La clase PrincipalPermission permite comprobar los permisos declarativos e imperativos con la entidad de seguridad activa.The PrincipalPermission class allows both declarative and imperative permission checks against the active principal.

Para determinar si el código tiene autorización para el acceso a un recurso o para ejecutar una operación, el sistema de seguridad en tiempo de ejecución atraviesa la pila de llamadas y compara los permisos concedidos a cada llamador con el permiso que se exige.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. Si algún llamador de la pila de llamadas no tiene el permiso exigido, se iniciará clase SecurityException y se rechazará el acceso.If any caller in the call stack does not have the demanded permission, a SecurityException is thrown and access is refused.

Solicitar permisosRequesting Permissions

La finalidad de solicitar permisos es informar al motor en tiempo de ejecución de los permisos que necesita la aplicación para ejecutarse y garantizar que solo recibe los permisos que realmente necesita.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. Por ejemplo, si la aplicación necesita acceso de escritura al disco local, requiere FileIOPermission.For example, if your application needs to write data to the local disk, it requires FileIOPermission. Si este permiso no se ha concedido, se producirán errores en la aplicación al intentar escribir en el disco.If that permission hasn't been granted, the application will fail when it attempts to write to the disk. Sin embargo, si la aplicación solicita FileIOPermission y el permiso no se concede, generará la excepción al comienzo y no se cargará.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.

En un escenario donde la aplicación solo necesita leer datos del disco, puede solicitar que nunca se le concedan permisos de escritura.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. En el caso de se produzca un error o un ataque malintencionado, el código no podrá dañar los datos con los que trabaja.In the event of a bug or a malicious attack, your code cannot damage the data on which it operates. Para obtener más información, consulte solicitar permisos.For more information, see Requesting Permissions.

Seguridad basada en roles y CASRole-Based Security and CAS

La implementación de la seguridad basada en roles y de la seguridad de acceso del código (CAS) mejora la seguridad global de la aplicación.Implementing both role-based security and code-accessed security (CAS) enhances overall security for your application. La seguridad basada en roles se puede basar en una cuenta de Windows o en una identidad personalizada, de forma que la información sobre la entidad de seguridad esté disponible en el subproceso actual.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. Además, a menudo se requiere a la aplicaciones que proporcionen acceso a datos o recursos basándose en credenciales proporcionadas por el usuario.In addition, applications are often required to provide access to data or resources based on credentials supplied by the user. Normalmente, dichas aplicaciones comprueban la función de un usuario y proporcionan acceso a los recursos basándose en dichos roles.Typically, such applications check the role of a user and provide access to resources based on those roles.

La seguridad basada en roles permite que un componente identifique los usuarios actuales y sus roles asociados en tiempo de ejecución.Role-based security enables a component to identify current users and their associated roles at run time. Esta información se asigna a continuación mediante una directiva CAS para determinar el conjunto de permisos que se conceden en tiempo de ejecución.This information is then mapped using a CAS policy to determine the set of permissions granted at run time. En un dominio de aplicación especificado, el host puede cambiar la directiva de seguridad predeterminada basada en roles y establecer una entidad de seguridad que represente a un usuario y a los roles asociados al usuario.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 usa permisos para implementar su mecanismo a fin de aplicar restricciones en el código administrado.The CLR uses permissions to implement its mechanism for enforcing restrictions on managed code. Los permisos de seguridad basada en roles proporcionan un mecanismo para descubrir si un usuario (o el agente que actúa en su nombre) tiene una identidad concreta o es miembro de una función especificada.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. Para obtener más información, vea permisos de seguridad.For more information, see Security Permissions.

En función del tipo de aplicación que cree, deberá considerar también la posibilidad de implementar permisos basados en roles en la base de datos.Depending on the type of application you are building, you should also consider implementing role-based permissions in the database. Para obtener más información sobre la seguridad basada en roles en SQL Server, consulte SQL Server Security.For more information on role-based security in SQL Server, see SQL Server Security.

EnsambladosAssemblies

Los ensamblados componen la unidad fundamental de implementación, control de versiones, reutilización, ámbito de activación y permisos de seguridad en una aplicación de .NET Framework.Assemblies form the fundamental unit of deployment, version control, reuse, activation scoping, and security permissions for a .NET Framework application. Un ensamblado proporciona una colección de tipos y recursos creados para funcionar en conjunto y formar una unidad lógica de funcionalidad.An assembly provides a collection of types and resources that are built to work together and form a logical unit of functionality. En CLR, un tipo no existe si no es en el contexto de un ensamblado.To the CLR, a type does not exist outside the context of an assembly. Para obtener más información sobre la creación e implementación de ensamblados, vea programar con ensamblados.For more information on creating and deploying assemblies, see Programming with Assemblies.

Ensamblados con nombre seguroStrong-naming Assemblies

Un nombre seguro, o firma digital, consta de la identidad del ensamblado, que incluye su nombre de texto sencillo, el número de versión, la información de referencia cultural (si se proporciona), así como una clave pública y una firma digital.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. La firma digital se genera a partir de un archivo de ensamblado que usa la clave privada correspondiente.The digital signature is generated from an assembly file using the corresponding private key. El archivo de ensamblado contiene el manifiesto del ensamblado, que contiene los nombres y códigos hash de todos los archivos que forman el ensamblado.The assembly file contains the assembly manifest, which contains the names and hashes of all the files that make up the assembly.

La asignación de un nombre seguro al ensamblado proporciona a una aplicación o a un componente una identidad única que puede usar otro software para referirse a ella de manera explícita.Strong naming an assembly gives an application or component a unique identity that other software can use to refer explicitly to it. La asignación de nombres seguros protege a los ensamblados de la suplantación por parte de un ensamblado que contenga código malintencionado.Strong naming guards assemblies against being spoofed by an assembly that contains hostile code. También garantiza la coherencia entre las diferentes versiones de un componente.Strong-naming also ensures versioning consistency among different versions of a component. Debe usar nombres seguros en los ensamblados que se van a implementar en la caché global de ensamblados (GAC).You must strong name assemblies that will be deployed to the Global Assembly Cache (GAC). Para obtener más información, vea Crear y utilizar ensamblados con nombre seguro.For more information, see Creating and Using Strong-Named Assemblies.

Confianza parcial en ADO.NET 2.0Partial Trust in ADO.NET 2.0

En ADO.NET 2.0, se pueden ejecutar los proveedores de datos .NET Framework para SQL Server, OLE DB, ODBC y para Oracle en entornos de confianza parcial.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. En versiones anteriores de .NET Framework, solo se admitía el uso de System.Data.SqlClient en aplicaciones que no fuesen de plena confianza.In previous releases of the .NET Framework, only System.Data.SqlClient was supported in less than full-trust applications.

Una aplicación de confianza parcial que utilice el proveedor de SQL Server debe tener como mínimo permisos de ejecución y SqlClientPermission.At minimum, a partially trusted application using the SQL Server provider must have execution and SqlClientPermission permissions.

Propiedades de atributos de permiso de confianza parcialPermission Attribute Properties for Partial Trust

En las situaciones de confianza parcial, se puede aplicar SqlClientPermissionAttribute a los miembros a fin de restringir aún más las capacidades disponibles para el proveedor de datos .NET Framework para 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.

En la siguiente tabla se muestran y se describen las propiedades SqlClientPermissionAttribute disponibles:The following table lists the available SqlClientPermissionAttribute properties and their descriptions:

Propiedad de atributo de permisoPermission attribute property DescripciónDescription
Action Obtiene o establece una acción de seguridad.Gets or sets a security action. Se hereda de SecurityAttribute.Inherited from SecurityAttribute.
AllowBlankPassword Habilita o deshabilita el uso de una contraseña en blanco en una cadena de conexión.Enables or disables the use of a blank password in a connection string. Los valores válidos son true (para habilitar el uso de contraseñas en blanco) y false (para deshabilitarlo).Valid values are true (to enable the use of blank passwords) and false (to disable the use of blank passwords). Se hereda de DBDataPermissionAttribute.Inherited from DBDataPermissionAttribute.
ConnectionString Identifica una cadena de conexión admitida.Identifies a permitted connection string. Se pueden identificar varias cadenas de conexión.Multiple connection strings can be identified. Nota: No incluya un identificador de usuario ni una contraseña en la cadena de conexión.Note: Do not include a user ID or password in your connection string. En esta versión no se pueden modificar las restricciones de las cadenas de conexión mediante la herramienta Configuración de .NET Framework.In this release, you cannot change connection string restrictions using the .NET Framework Configuration Tool.

Se hereda de DBDataPermissionAttribute.Inherited from DBDataPermissionAttribute.
KeyRestrictions Identifica qué parámetros de las cadenas de conexión están permitidos o no lo están.Identifies connection string parameters that are allowed or disallowed. Los parámetros de la cadena de conexión se identifican con el formato <nombre de parámetro > = .Connection string parameters are identified in the form <parameter name>=. Se pueden especificar varios parámetros separados por punto y coma (;).Multiple parameters can be specified, delimited using a semicolon (;). Nota: Si no especifica KeyRestrictions, pero establece KeyRestrictionBehavior propiedad en AllowOnly o PreventUsage, no se permite ningún parámetro de cadena de conexión adicional.Note: If you do not specify KeyRestrictions, but you set KeyRestrictionBehavior property to AllowOnly or PreventUsage, no additional connection string parameters are allowed. Se hereda de DBDataPermissionAttribute.Inherited from DBDataPermissionAttribute.
KeyRestrictionBehavior Identifica los parámetros de cadenas de conexión como los únicos parámetros adicionales permitidos (AllowOnly) o bien identifica los parámetros adicionales no permitidos (PreventUsage).Identifies the connection string parameters as the only additional parameters allowed (AllowOnly), or identifies the additional parameters that are not allowed (PreventUsage). AllowOnly es el valor predeterminado.AllowOnly is the default. Se hereda de DBDataPermissionAttribute.Inherited from DBDataPermissionAttribute.
TypeID Obtiene un identificador único para el atributo cuando se implementa en una clase derivada.Gets a unique identifier for this attribute when implemented in a derived class. Se hereda de Attribute.Inherited from Attribute.
Unrestricted Indica si se declaran permisos protegidos para el origen.Indicates whether unrestricted permission to the resource is declared. Se hereda de SecurityAttribute.Inherited from SecurityAttribute.

Sintaxis de ConnectionStringConnectionString Syntax

En el siguiente ejemplo se muestra cómo se utiliza el elemento connectionStrings de un archivo de configuración para permitir únicamente el uso de una determinada cadena de conexión.The following example demonstrates how to use the connectionStrings element of a configuration file to allow only a specific connection string to be used. Vea cadenas de conexión para obtener más información sobre cómo almacenar y recuperar cadenas de conexión de archivos de configuración.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>  

Sintaxis de KeyRestrictionsKeyRestrictions Syntax

En el ejemplo siguiente se habilita la misma cadena de conexión, se habilita el uso de las opciones de cadena de conexión Encrypt y Packet Size, pero se restringe el uso de otras opciones de cadena de conexión.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>  

Sintaxis de KeyRestrictionBehavior con PreventUsageKeyRestrictionBehavior with PreventUsage Syntax

En el ejemplo siguiente se habilita la misma cadena de conexión y se permiten todos los demás parámetros de conexión, excepto User Id, Password y 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>  

Sintaxis de KeyRestrictionBehavior con AllowOnlyKeyRestrictionBehavior with AllowOnly Syntax

En el ejemplo siguiente se habilitan dos cadenas de conexión que contienen los parámetros Initial Catalog, Connection Timeout, Encrypt y Packet Size.The following example enables two connection strings that also contain Initial Catalog, Connection Timeout, Encrypt, and Packet Size parameters. El resto de los parámetros de cadenas de conexión están restringidos.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>  

Habilitar confianza parcial con un conjunto de permisos personalizadosEnabling Partial Trust with a Custom Permission Set

Para habilitar el uso de permisos System.Data.SqlClient para una zona determinada, un administrador del sistema debe crear un conjunto de permisos personalizados y establecerlo como el conjunto de permisos de dicha zona.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. Los conjuntos de permisos predeterminados, como LocalIntranet, no se pueden modificar.Default permission sets, such as LocalIntranet, cannot be modified. Por ejemplo, para incluir System.Data.SqlClient permisos para el código que tiene un Zone de LocalIntranet, un administrador del sistema puede copiar el conjunto de permisos para LocalIntranet, cambiarle el nombre a "CustomLocalIntranet", agregar los permisos de System.Data.SqlClient, importar CustomLocalIntranet conjunto de permisos mediante la herramienta Caspol. exe (herramienta de la Directiva de seguridad de acceso del código)y establezca el conjunto de permisos de LocalIntranet_Zone en 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.

Conjunto de permisos de ejemploSample Permission Set

A continuación se muestra un ejemplo de un conjunto de permisos para el proveedor de datos .NET Framework para SQL Server en un escenario que no es de plena confianza.The following is a sample permission set for the .NET Framework Data Provider for SQL Server in a partially trusted scenario. Para obtener información sobre cómo crear conjuntos de permisos personalizados, vea configurar conjuntos de permisos mediante 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>  

Comprobar el acceso a código de ADO.NET mediante permisos de seguridadVerifying ADO.NET Code Access Using Security Permissions

En las situaciones de confianza parcial, puede solicitar privilegios de seguridad de acceso del código para determinados métodos en el código mediante la especificación de SqlClientPermissionAttribute.For partial-trust scenarios, you can require CAS privileges for particular methods in your code by specifying a SqlClientPermissionAttribute. Si la directiva de seguridad restringida no permite el privilegio, se inicia una excepción antes de ejecutarse el código.If that privilege is not allowed by the restricted security policy in effect, an exception is thrown before your code is run. Para obtener más información sobre la Directiva de seguridad, consulte prácticas recomendadaspara la Directiva de seguridad y Administración de directivas de seguridad.For more information on security policy, see Security Policy Management and Security Policy Best Practices.

EjemploExample

En el siguiente ejemplo se muestra cómo escribir código que requiera una determinada cadena de conexión.The following example demonstrates how to write code that requires a particular connection string. Simula la denegación de permisos sin restricciones para System.Data.SqlClient, que podría implementar un administrador del sistema en una situación real mediante una directiva de seguridad CAS.It simulates denying unrestricted permissions to System.Data.SqlClient, which a system administrator would implement using a CAS policy in the real world.

Importante

Al diseñar permisos de seguridad CAS en ADO.NET, el procedimiento correcto es comenzar con el caso más restrictivo (sin ningún permiso) y agregar a continuación los permisos específicos necesarios para la tarea determinada que el código debe realizar.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. El patrón opuesto, que comienza con todos los permisos y deniega a continuación un permiso concreto, no es seguro puesto que existen muchas formas de expresar la misma cadena de conexión.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. Por ejemplo, si comienza con todos los permisos y después intenta denegar el uso de la cadena de conexión "servidor=unServidor", la cadena "servidor=unServidor.miEmpresa.com" seguirá obteniendo permiso.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. Al comenzar siempre por no conceder ningún permiso, se reduce la posibilidad de que haya lagunas en el conjunto de permisos.By always starting by granting no permissions at all, you reduce the chances that there are holes in the permission set.

En el siguiente código se muestra cómo SqlClient realiza la petición de seguridad, que inicia SecurityException si los permisos de seguridad CAS adecuados no se encuentran en su lugar.The following code demonstrates how SqlClient performs the security demand, which throws a SecurityException if the appropriate CAS permissions are not in place. El resultado SecurityException se muestra en la ventana de la consola.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

Debe poder ver este resultado en la ventana de la consola: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.  

Interoperabilidad de código no administradoInteroperability with Unmanaged Code

El código que se ejecuta fuera de CLR se denomina código no administrado.Code that runs outside the CLR is called unmanaged code. Por lo tanto, los mecanismos de seguridad como CAS no se pueden aplicar en código no administrado.Therefore, security mechanisms such as CAS cannot be applied to unmanaged code. Los componentes COM, las interfaces ActiveX y las funciones de la API de Windows son ejemplos de código no administrado.COM components, ActiveX interfaces, and Windows API functions are examples of unmanaged code. Cuando se ejecuta código no administrado se aplican consideraciones de seguridad especiales, de forma que no se ponga en peligro la seguridad global de la aplicación.Special security considerations apply when executing unmanaged code so that you do not jeopardize overall application security. Para más información, consulte Interoperating with Unmanaged Code (Interoperar con código no administrado)For more information, see Interoperating with Unmanaged Code.

.NET Framework también es compatible con versiones anteriores de componentes COM existentes mediante el acceso a través de la interoperabilidad COM.The .NET Framework also supports backward compatibility to existing COM components by providing access through COM interop. Se pueden incluir componentes COM en una aplicación de .NET Framework usando las herramientas de la interoperabilidad COM para importar los tipos COM necesarios.You can incorporate COM components into a .NET Framework application by using COM interop tools to import the relevant COM types. Una vez que se han importado, los tipos COM están listos para su uso.Once imported, the COM types are ready to use. La interoperabilidad COM también permite que los clientes COM tengan acceso a código administrado mediante la exportación de metadatos de ensamblado a una biblioteca de tipos y mediante el registro del componente administrado como un componente 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. Para obtener más información, consulte interoperabilidad com avanzada.For more information, see Advanced COM Interoperability.

Vea tambiénSee also