Diseñar un permiso

Un permiso representa la posibilidad de obtener acceso a un recurso protegido o de realizar una operación protegida. Cuando se implementa una clase de permiso propia, se han de tomar varias decisiones de diseño de alto nivel. Uno de los primeros pasos consiste en determinar exactamente qué recurso va a proteger el permiso personalizado.

A continuación, se debe decidir si hay problemas relacionados con la superposición de permisos. Aunque seguramente se desea evitar que dos permisos protejan el mismo recurso, en algunas circunstancias esto no se puede evitar de manera razonable. Por ejemplo, el permiso para obtener acceso a código no administrado puede abarcar también otros permisos, porque el código que recibe el permiso de acceso a código no administrado puede realizar prácticamente cualquier operación a través de una API no administrada. Sin embargo, cuando no se concede permiso para obtener acceso a código no administrado, es necesario conceder permisos para obtener acceso a otros recursos específicos. Por tanto, es razonable que el permiso de acceso a código no administrado esté separado de otros permisos.

¿Cómo se sabe si una superposición de permisos es factible? No hay una respuesta absoluta, pero una de las cuestiones que se deben considerar es si uno de los permisos representa un acceso más específico que el otro y, por ello, se concederá más fácilmente. Si es así, la concesión de derechos de acceso es sencilla en la mayoría de los casos, lo cual simplifica la labor del administrador.

Tras decidir qué recurso va a proteger el permiso y resolver los problemas relacionados con la superposición de los permisos, deberá decidir cómo de específico debe ser el control de acceso. La respuesta a esta pregunta afecta a la forma de diseñar las variables que representan el estado del permiso y determina si los administradores pueden configurar el acceso al recurso protegido. También puede afectar al rendimiento, a la facilidad de uso y a otros factores.

Para ilustrar algunas de estas cuestiones de diseño, considere algunos de los diseños que podían haberse elegido para FileIOPermission (Clase) que proporciona .NET Framework. Cada opción de diseño afecta a las variables que representan el estado del permiso.

  • Un solo bit que significa "usar todos los archivos" o "no usar ningún archivo", dependiendo de su valor.

  • Dos bits que significan "leer todos los archivos" y "escribir todos los archivos", o no, dependiendo de sus valores.

  • 26 bits que significan "usar todos los archivos de la unidad especificada".

  • Una matriz de cadenas que enumeran todos los archivos a los que se concede acceso.

Claramente, existen pros y contras que hay que considerar. Por ejemplo, el permiso de un solo bit es muy sencillo, rápido y fácil de comprender, pero presenta una opción de todo o nada para los administradores, lo que puede no ser deseable. Otras opciones que especifican una representación más compleja del estado del permiso pueden reducir el rendimiento en cierta medida. Es preciso sopesar estas ventajas y desventajas y tener en cuenta que no se debe crear más de un permiso para proteger el mismo recurso. En general, la clase de permiso debe diseñarse de modo que el estado del permiso sea tan complejo como sea necesario, sin que tenga un impacto demasiado grande sobre el rendimiento.

Aunque existen otras posibilidades de diseño, la mayoría de los permisos siguen uno de los modelos de diseño estándar o una combinación de los mismos:

  • Permisos booleanos. Esta clase de objeto de permiso más sencilla tiene uno o más bits, cada uno de los cuales se corresponde con "permiso para hacer X". O se tiene el permiso o no se tiene. Un ejemplo de este tipo de permiso es SecurityPermission (Clase), cuyo estado contiene variables booleanas que representan el derecho de realizar diferentes operaciones, como el permiso de llamar a código no administrado, cada una de las cuales se permite o no.

  • Niveles de permisos. Esta forma de permiso más detallada tiene variables que representan cada tipo de acceso como un número comprendido entre el cero (ningún acceso en absoluto) y un número mayor (acceso totalmente ilimitado), con algunos niveles entre ambos. Por ejemplo, se puede utilizar UIPermission (Clase) con el fin de expresar distintos niveles de permiso para utilizar ventanas, desde la ausencia de permiso de interfaz de usuario hasta un permiso de interfaz de usuario ilimitado, con algunos pasos entre ambos.

  • Permisos de listas de objetos. Este tipo de permiso proporciona una especificación muy detallada de lo que se permite y lo que no. FileIOPermission (Clase) es un buen ejemplo de este tipo de permiso porque su estado está representado por listas de archivos para los que se permiten determinados tipos de acceso. Los permisos con listas son más útiles para proteger los recursos que contienen un gran número de objetos con nombre.

En general, se recomienda reducir al mínimo las dependencias externas en la clase de permiso personalizada, porque cada ensamblado del que dependa el permiso tendrá que cargarse cuando el sistema de seguridad necesite la clase de permiso. Otra razón para minimizar las dependencias es que cada ensamblado utilizado por la clase de permiso personalizada (excepto Mscorlib) debe agregarse a la lista de total confianza. (Para obtener más información, vea Actualizar la directiva de seguridad.) Si es posible, se debe colocar el permiso personalizado y las clases de atributo asociadas en un ensamblado independiente para reducir así la posibilidad de que otros ensamblados se carguen innecesariamente.

Nota

Los permisos personalizados se deben marcar como sealed (NotInheritable en Visual Basic) o colocar una demanda de herencia en ellos. En caso contrario, los llamadores maliciosos puede derivar de su permiso y crear, posiblemente, puntos vulnerables de seguridad.

Vea también

Conceptos

Crear permisos de acceso a código propios

Otros recursos

Seguridad de acceso a código