Peticiones
Actualización: noviembre 2007
Puede utilizar la llamada de petición de seguridad declarativamente o imperativamente para especificar los permisos que deben poseer los llamadores directos o indirectos para obtener acceso a la biblioteca. Los llamadores directos llaman explícitamente a los métodos estáticos o de instancia de la biblioteca, mientras que los llamadores indirectos llaman a los métodos estáticos o de instancia de otra biblioteca que llama a su biblioteca. Cuando utiliza una petición, cualquier aplicación que incluya el código se ejecutará únicamente si todos los llamadores directos e indirectos tienen los permisos que especifica la petición. Las peticiones son especialmente útiles cuando la biblioteca de clases utiliza recursos protegidos que no desea que sean accesibles para el código que no es de confianza. Las peticiones se pueden colocar en código mediante la sintaxis imperativa o declarativa.
Tenga presente que la mayoría de las clases de .NET Framework ya tienen peticiones asociadas, por lo que no es necesario realizar una petición adicional siempre que utilice una clase que tenga acceso a un recurso protegido. Por ejemplo, la clase StreamWriter realiza automáticamente una petición de seguridad de FileIOPermission cada vez que se abre. Si realiza una petición de FileIOPermission cuando utiliza la clase StreamWriter, hará que se produzca un recorrido de pila redundante e ineficaz. Las peticiones deben usarse para proteger los recursos personalizados que requieran permisos personalizados.
Las peticiones pueden ser declarativas o imperativas.
Recorridos de pila
Las peticiones aplican la seguridad por medio de la realización de un análisis (denominado recorrido de pila) donde se examinan todas las funciones de llamada (o marco de pila) de la pila de llamadas actual para el permiso especificado. Cuando se desencadena una petición, ocurre lo siguiente.
El recorrido de pila comienza en el marco de pila de los llamadores, no en la pila actual donde se efectúa la petición. Por ejemplo, si el método A llama al método B y método B tiene una petición, el recorrido de pila comienza en el marco de pila del método A. El método B no se evaluará nunca como parte del recorrido de pila.
El recorrido de pila proseguirá a lo largo de la pila de llamadas hasta que alcance el punto de entrada de programa de la pila (normalmente el método Main) o hasta que encuentre un modificador de recorrido de pila, como Assert. Para obtener información sobre los modificadores de recorrido de pila, vea Invalidar comprobaciones de seguridad.
Cuando aparezcan una petición y un modificador de pila (como, por ejemplo, Assert) para el mismo permiso en el mismo marco de pila, la petición tendrá prioridad.
La sintaxis declarativa e imperativa no presentan ninguna diferencia de comportamiento.
Tenga presente que una petición situada en el punto de entrada del programa no se evaluará nunca porque los recorridos de pila siempre comienzan en el marco de pila de llamada, pero en este caso, no existe un marco de llamada que evaluar. Por lo tanto, las peticiones situadas en un punto de entrada del programa siempre se realizarán correctamente.
Peticiones declarativas
Las solicitudes declarativas colocan información en los metadatos del código mediante atributos. Puede utilizar la sintaxis declarativa para colocar una petición en el nivel de clase o de método del código.
Si coloca una comprobación de seguridad declarativa en el nivel de clase, ésta se aplicará a cada miembro de la clase. Sin embargo, si coloca una comprobación de seguridad declarativa en el nivel de miembro, sólo se aplicará a ese miembro y reemplazará el permiso especificado en el nivel de clase, si existiese. Por ejemplo, supongamos que especifica en el nivel de clase que se requiere PermisoA y para Método 1 de esa clase indica que se requiere PermisoB. Cuando se llama a Método1, la comprobación de seguridad buscará sólo PermisoB, pero los demás métodos de la clase seguirán requiriendo PermisoA.
En el ejemplo siguiente se coloca una petición declarativa de un permiso personalizado denominado CustomPermission en todos los llamadores del método ReadData. Este permiso es un permiso personalizado hipotético y no existe en .NET Framework. El permiso personalizado tiene un atributo CustomPermissionAttribute definido por separado que realiza la petición. En este caso, utiliza un indicador SecurityAction.Demand para especificar el tipo de petición que realizará el atributo.
<CustomPermissionAttribute(SecurityAction.Demand, Unrestricted := True)>Public Shared Function ReadData() As String
'Read from a custom resource.
End Function
[CustomPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
public static string ReadData()
{
//Read from a custom resource.
}
Peticiones imperativas
Las peticiones imperativas se colocan en el nivel de método del código mediante la creación de una nueva instancia de un objeto de permiso y mediante una llamada al método Demand de ese objeto. La sintaxis imperativa no se puede utilizar para colocar peticiones en el nivel de clase.
La petición imperativa que se coloca en el código ayuda a proteger eficazmente todo el código restante del método en el que se llama al método Demand. La comprobación de seguridad se realiza cuando se ejecuta Demand; si se produce un error en la comprobación de seguridad, se producirá una excepción SecurityException y el resto del código de ese método o miembro nunca se ejecutará, a menos que se detecte y se controle SecurityException.
En el ejemplo siguiente se utiliza la sintaxis imperativa para colocar una petición en todos los llamadores del permiso personalizado CustomPermission. Este código crea una nueva instancia de la clase CustomPermission y pasa el indicador PermissionState.Unrestricted al constructor. A continuación, se llama al método Demand.
Public Shared Sub ReadData()
Dim MyPermission As New CustomPermission(PermissionState.Unrestricted)
MyPermission.Demand()
'Read from a custom resource.
End Sub
public static void ReadData()
{
CustomPermission MyPermission = new CustomPermission(PermissionState.Unrestricted);
MyPermission.Demand();
//Read from a custom resource.
}
Nota: |
---|
El comportamiento de optimización de la operación de petición es distinto en las plataformas de 64 y 32 bits. En las plataformas de 64 bits, una petición no comprobará el conjunto concedido del ensamblado que contiene la petición en casos en los que no haya otros ensamblados de llamada presentes. Sin embargo, esta optimización no produce ninguna elevación de privilegios ya que se sigue realizando un recorrido de pila cuando hay ensamblados de llamada presentes. En el caso de las plataformas de 32 bits, la operación de petición comprueba el conjunto concedido del ensamblado que contiene la petición y todos los ensamblados de llamada. |
Vea también
Conceptos
Crear permisos de acceso a código propios
Agregar compatibilidad con la seguridad declarativa
Escribir bibliotecas de clases seguras