Share via


Utilizar el método Deny

Actualización: noviembre 2007

Cuando se llama a Deny, se impide el acceso al recurso especificado por el permiso denegado. Si el código llama a Deny y después un llamador indirecto reclama el permiso denegado, se producirá un error en la comprobación de seguridad, incluso si todos los llamadores tienen permiso de acceso a ese recurso. Para que Deny tenga efecto, no es necesario que el permiso reclamado y el permiso denegado coincidan exactamente, ni el permiso reclamado tiene que ser un subconjunto del permiso denegado. No obstante, si la intersección de los dos permisos está vacía (es decir, si no tienen nada en común), la llamada a Deny no tendrá efecto. Hay que tener en cuenta que Deny no puede reemplazar el código que se encuentra más abajo en la pila de llamadas que realiza Assert. Si el código que está más abajo en la pila de llamadas llama a Assert, dicho código puede obtener acceso al recurso que un código situado más arriba en la pila de llamadas deniega.

Puede utilizar llamadas a Deny en el código para evitar responsabilidades, porque Deny impide que el código se utilice para obtener acceso al recurso denegado. Sin embargo, la llamada a Deny no bloquea futuras aserciones de seguridad realizadas por llamadores indirectos.

En la ilustración siguiente se muestra lo que sucede cuando se utiliza Deny. Supongamos que las instrucciones siguientes son verdaderas para los ensamblados A, B, C, D y E, y el permiso P1:

  • P1 representa el derecho de leer todos los archivos de la unidad C.

  • Los ensamblados A, B, C, D y E han recibido P1.

  • El método F coloca una petición en el permiso P1.

  • El método C crea una instancia de la clase P1 y, después, llama al método Deny de P1.

  • El método A está incluido en el ensamblado A, el método B en el ensamblado B, y así sucesivamente.

Utilizar Deny

La llamada del método C a Deny puede afectar al resultado de las peticiones de P1. Supongamos, por ejemplo, que el método A llama a B, B llama a C, C llama a E y E llama a F. Dado que el método F obtiene acceso directo al recurso que protege P1, el método F invoca una comprobación de seguridad para P1 mediante una llamada al método Demand de P1 (o mediante una petición declarativa). Esta petición hace que el motor en tiempo de ejecución compruebe los permisos de todos los llamadores de la pila de llamadas, empezando por el ensamblado E. Dado que el ensamblado E ha recibido el permiso P1, el motor en tiempo de ejecución procede a examinar los permisos del ensamblado C. Sin embargo, como el método C ha denegado P1, en ese momento se produce un error en la comprobación de seguridad invocada por el método E y se produce una excepción SecurityException. No importa que el ensamblado C y sus llamadores (los ensamblados A y B) hayan recibido P1; se siguen produciendo errores en la comprobación de seguridad. Como el método C llamó a Deny, el código de los ensamblados A y B no puede obtener acceso al recurso protegido por P1.

En el siguiente código se muestra una sintaxis declarativa para reemplazar las comprobaciones de seguridad con el método Deny. En este ejemplo, la sintaxis ReflectionPermission especifica dos valores: una enumeración SecurityAction y el valor de la propiedad TypeInformation. TypeInformation se establece en true para especificar que este permiso representa el derecho de ver miembros privados mediante la reflexión y se pasa SecurityAction.Deny para denegar ese permiso. Para obtener una lista completa de los valores que se pueden especificar, vea la descripción de ReflectionPermission. Con esta declaración de seguridad, el método no puede leer miembros privados de un tipo mediante la reflexión.

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

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

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

En el siguiente código se muestra una sintaxis imperativa para reemplazar las comprobaciones de seguridad con el método Deny. En este ejemplo, se declara el objeto ReflectionPermission y se pasa ReflectionPermissionFlag.TypeInformation a su constructor para inicializar el permiso actual. Cuando se llama al método Deny, nunca se puede utilizar el código ni los llamadores para leer campos privados mediante la reflexión.

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

public class MyClass {
   public MyClass() {    
   }   

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

      // Access public members through reflection.
   }  
}

Problemas de canonización con Deny

Es necesario extremar las precauciones al denegar los permisos FileIOPermission, RegistryPermission, WebPermission, UrlIdentityPermission, SiteIdentityPermission y EnvironmentPermission porque los archivos individuales, las entradas del Registro, las direcciones URL y las rutas de acceso del sistema se pueden describir mediante varios nombres. Por ejemplo, se puede hacer referencia a un único archivo, MiArchivo.log, de muchas maneras "c:\MiArchivo.log" y "\\Nombre_de_mi_equipo\c$\MiArchivo.log". Si crea un permiso que representa el acceso a "c:\MiArchivo.log" y, a continuación, deniega ese permiso para su código, el código sigue teniendo acceso al archivo mediante la ruta de acceso alternativa "\\Nombre_de_mi_equipo\c$\MiArchivo.txt".

Puede utilizar una combinación de PermitOnly y Deny para evitar problemas con la resolución de nombres canónicos. PermitOnly proporciona la capacidad de especificar sólo uno de los diversos nombres que pueda tener un recurso y tiene el efecto secundario de denegar el acceso a ese recurso si se utiliza otro nombre. Después de utilizar PermitOnly para especificar el nombre permitido para un recurso, deberá utilizar Deny para rechazar el acceso al recurso si se utiliza ese nombre.

En el código siguiente se utiliza una combinación de Deny y PermitOnly para impedir el acceso del código a un recurso denominado MyLog.log. Este código también bloquea el acceso al recurso si se utilizan todos los nombres o rutas de acceso alternativos.

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

Vea también

Conceptos

Invalidar comprobaciones de seguridad

Referencia

SecurityAction

RegistryPermissionAttribute

Otros recursos

Extender metadatos mediante atributos

Seguridad de acceso a código