Seguridad
Introducción
En una empresa, el administrador de sistemas define la política de seguridad global del sistema y, en ningún caso, se puede quebrantar esta seguridad mediante código. El administrador fija las funciones de cada uno de los usuarios y grupos, usando para ello Active Directory. De esta seguridad basada en roles resultan las autorizaciones. Estas autorizaciones pueden ser obligatorias, es decir, se pide el permiso en tiempo de ejecución, o declarativas, es decir, el ensamblado va a especificar los permisos necesarios para su ejecución. En caso de conflicto, el ensamblado y por tanto la aplicación no se podrán ejecutar.
Los elementos básicos
1. La interfaz IPermission
Las clases que definen los permisos se encuentran en el espacio de nombres System.Security.Permissions y son el núcleo del proceso de seguridad. Existen diferentes clases para diferentes tipos de permisos. Por ejemplo, el acceso al sistema de archivos se gestiona mediante la clase FileIOPermission, el acceso a las variables del registro mediante la clase RegistryPermission y el acceso a las variables de entorno mediante la clase EnvironmentPermission.
Todas estas clases implementan la interfaz IPermission, que implementa los métodos comunes a los permisos:
-
Copy: devuelve una copia de la autorización actual.
-
Demand: realiza una comprobación de los permisos y devuelve una excepción del tipo SecurityException si las condiciones no se cumplen.
-
Intersect: devuelve una nueva autorización que representa la intersección de la autorización actual con la que se pasa como argumento.
-
IsSubsetOf: devuelve un valor booleano que indica si la autorización actual es un sub-conjunto de la que se pasa como argumento.
-
Union: devuelve una nueva autorización que representa la unión de la autorización actual y de la que se pasa como argumento.
2. La clase CodeAccessPermission
Todos los permisos de acceso heredan de la clase abstracta CodeAccessPermission, que implementa la interfaz IPermission. Como consecuencia, exponen un conjunto de miembros comunes...
Implementación de la seguridad
1. La seguridad basada en roles
La seguridad basada en roles permite permitir o rechazar el acceso a una parte de la aplicación o de los recursos en función de la identidad del usuario. El principio básico es disponer, por un lado, de un usuario y, por otro, de un permiso. El acceso se realiza únicamente si el usuario cumple las condiciones del permiso.
La seguridad permite gestionar con facilidad el acceso a las diferentes partes de una aplicación. Tomemos como ejemplo la aplicación SelfMailer. Es posible definir, por ejemplo, que solo un administrador pueda utilizar el menú Enviar. Para realizar esta tarea, debe empezar creando un nuevo objeto PrincipalPermission especificando una identidad y/o un rol en el constructor del formulario Main:
PrincipalPermission permiso = new PrincipalPermission(
@"LAPTOP-WIN-7352\Pedro",
null);
A continuación, puede iniciar la comprobación del permiso llamando al método Demand. Este método genera una excepción del tipo SecurityException si el usuario no tiene las autorizaciones exigidas por el permiso:
try
{
permiso.Demand();
}
catch (SecurityException ex)
{
this.enviarToolStripMenuItem.Visible = false;
}
En caso de que varios usuarios deban tener la autorización para acceder a una parte de la aplicación, es posible utilizar el método Union para crear un nuevo permiso combinando otros dos:
PrincipalPermission...
Introducción a la criptografía
Los datos sensibles se deben dotar de seguridad para que solo los usuarios con permiso puedan consultarlos. El cifrado es una manera de dotar de seguridad a la información. Existen algoritmos de cifrado simétricos y otros asimétricos. Un algoritmo de cifrado simétrico utiliza la misma clave para el cifrado y el descifrado, mientras que un algoritmo de cifrado asimétrico utilizara claves diferentes para el cifrado y el descifrado: una clave pública y una privada. De esta manera, los datos se pueden cifrar con la clave privada y descifrar con la clave pública o a la inversa, nunca con la misma clave. El Framework .NET contiene muchas clases que permiten gestionar la criptografía. Están en el espacio de nombres System.Security.Cryptography. El Hash es otra técnica de criptografía, aunque su objetivo no es dotar de seguridad a los datos, sino garantizar su integridad. El objetivo de los algoritmos Hash es crear un valor de longitud fija a partir de una fuente de longitud variable. Estos algoritmos se utilizan para las declaraciones numéricas y para comprobar la integridad de los datos. Un dato que se pase a un algoritmo Hash siempre dará el mismo resultado.
El proyecto de la aplicación SelfMailer se guarda en formato XML. La contraseña de la cuenta de correo electrónico es un dato legible. Vamos a ver cómo implementar...