Configurar la seguridad de un ensambladoPublicado el 14/Ago/2005
|
Introducción:
Cuando trabajamos con .NET Framework, si la aplicación se ejecuta desde nuestro equipo, normalmente no tendremos problemas de seguridad, (o de confianza), ya que el nivel de seguridad para nuestro equipo suele estar marcado como la más alta (Full Trust), pero si esa aplicación o alguna parte de la misma, no reside en nuestro equipo, bien porque se ejecute desde otro equipo de nuestra red local o bien porque se ejecute desde Internet, el nivel de seguridad o confianza (trust) no será el más alto, sino que se utilizará el que esté indicado en la configuración del propio .NET Framework.
Si necesitamos que un ensamblado en particular, o una serie de ensamblados firmados con nombre seguro (strong name), sea de confianza, debemos hacérselo saber al .NET Framework para que confíe en él y lo deje funcionar sin limitaciones, o al menos con las limitaciones que nosotros indiquemos.
Como ejemplo:
Usar un formulario externo incluido en un ensamblado DLLPara ver cómo configurar el nivel de confianza de un ensamblado que reside en otro equipo de nuestra red o bien que reside en un sitio de Internet, vamos a usar un ensamblado DLL el cual contendrá un formulario, ese formulario nos permitirá abrir un fichero que reside en nuestro equipo local, para abrir ese fichero lo haremos de dos formas: una será usando el cuadro de diálogos comunes de abrir fichero, la otra será usando arrastrar y soltar (drag & drop), ya que este tipo de acciones son de las que necesitan tener cierto tipo de privilegios, o confianza, para poder hacerlas.
Otra de las cosas que hará ese formulario contenido en una DLL será mostrar la versión del ensamblado, pueda que esto parezca una tontería, y realmente lo es, para averiguar esa versión usaremos clases del espacio de nombres System.Reflection, y el .NET Framework solo nos permitirá usar ese espacio de nombres si confía plenamente en nosotros, bueno, más que en nosotros habría que decir, en el ensamblado externo que queremos usar.Primero crearemos un ensamblado del tipo DLL, el cual contendrá un formulario con una serie de controles, los cuales realmente los usaremos para "rellenar", es decir, no será un formulario muy "práctico", salvo por el hecho de que podemos abrir un fichero o bien usar drag & drop para abrir cualquier fichero de textos, pero así y todo nos permitirá comprobar que funciona como si se tratara de un formulario normal y corriente, es decir, no notaremos que lo estamos ejecutando desde Internet, habría que aclarar que en lugar de decir: "ejecutarlo desde Internet", lo correcto sería decir: "ejecutar un ensamblado que hemos bajado de Internet", ya que la ejecución es local, incluso si nos desconectamos de Internet, seguirá funcionando.
Realmente la parte interesante de todo esto no estará en el propio formulario o en la librería que lo contiene, sino en cómo haremos para que lo podamos usar en nuestra aplicación de forma "natural".El formulario "remoto" y la aplicación cliente
Aunque aquí voy a mostrarte el código del formulario, el cual también está incluido en el ZIP con el código, realmente ese formulario no tendrás que "crearlo" o compilarlo, ya que te recomendaría que usaras el que yo tengo publicado en mi sitio, con idea de que así tengas el convencimiento de que todo funciona, y que no es ningún tipo de truco.
La aplicación cliente
También usaremos una aplicación cliente, con esa aplicación podrás acceder a ese formulario y usarlo. Esa aplicación realmente no es una utilidad genérica, que permita usar cualquier formulario externo, ya que internamente utiliza el nombre del formulario a cargar, así como el nombre de la clase del propio formulario, además del espacio de nombres en el que reside dicho formulario, (cuantos formularios ¿verdad?).
En la figura 1 tienes una captura de la aplicación cliente, desde la que podemos utilizar 5 ensamblados distintos, (los mostrados en el grupo de la izquierda).
Tres de esos ensamblados hacen lo indicado en la sección anterior, cada uno de esos tres ensamblados están compilados con las tres versiones de .NET Framework que hay actualmente, (mejor dicho, que hay a la hora de escribir este artículo, porque si esto lo lees dentro de cuatro o cinco años, lo mismo ya hay diez versiones del .NET, o más... ¡vaya usted a saber cuantos!).
El que está creado con la beta 2 de Visual Basic 2005 solo podremos usarlo desde una aplicación cliente generada también con VB2005 u otro lenguaje que compile con la versión 2.0 de .NET Framework.En el grupo de la derecha tenemos los sitios desde los que podemos usarlos. Los ensamblados creados con .NET v 1.x los tengo alojados en mi sitio "normal": www.elGuille.info. El creado con la beta 2 de .NET lo tengo alojado en el sitio de los foros, ya que en ese sitio está instalado el .NET 2.0 beta 2, y por tanto se pueden usar los ensamblados creados con la nueva versión de .NET. Por si quieres probarlo desde tu red local (intranet), he puesto una tercera opción en la que puedes indicar el path en el que has copiado el ensamblado. Ese path puede ser a un disco local, uno de la red o a un sitio de Internet.
Figura 1. La aplicación cliente en ejecución
Nota:
En los ZIP se incluye el código fuente de las librerías y los clientes, de las tres versiones de .NET, todos creados con Visual Basic.
También están los ejecutables y las DLL. Las DLL (y algunos ejecutables) están firmados con el fichero de nombre seguro que utilizo para mis aplicaciones de .NET. Te digo esto porque si vas a compilarlo te dirá que falta el fichero elGuille.snk, el cual no incluyo por razones de seguridad. Por tanto, te recomiendo que hagas una copia de las DLL y los EXE que se incluyen en los ficheros ZIP, y que si los vas a compilar, porque te apetezca hacer alguna modificación, deberías crearte un fichero .snk (strong name) para firmar al menos las DLL con nombre seguro, sino, es posible que no te funcionen todas esas librerías.
Para saber cómo firmar un ensamblado con nombre seguro léete este artículo.
Los formularios remotos
Como te he comentado, hay un total de cinco ensamblados DLL con el formulario que usaremos desde un sitio distinto a nuestro equipo.
Tres de esos formularios (las tres primeras opciones que hay en la aplicación cliente), tienen el mismo funcionamiento, la única diferencia entre ellos es la versión de .NET que he usado para compilarlos.
Los otros dos están creados con la versión 1.1 de .NET Framework, y la funcionalidad que le he dado es diferente a los otros tres, ya que desde esos formularios se puede acceder a una base de SQL Server, además de hacer algunas operaciones con el sistema de archivos: seleccionar un fichero, seleccionar un directorio y mostrar el contenido del mismo, guardar el contenido de un texto en un fichero, eliminar un fichero y poder arrastrar y soltar un fichero para abrirlo.
En las figuras 2 y 3 tienes una captura de ese formulario en pleno funcionamiento.
Figura 2. El formulario externo accediendo a una base de datos
Figura 3. El formulario accediendo al disco
La diferencia que hay entre esos dos ensamblados es que uno está firmado con nombre seguro y el otro no.
Configurar .NET para que confíe en los ensamblados externos
Antes de ver el código de los formularios y de la aplicación cliente que los usa, tenemos que indicarle al .NET que se fíe de esos ensamblados, si no queremos encontrarnos con una pantalla como la mostrada en las figuras 4 y 5.
Figura 4. Error producido por el cliente de .NET 2.0
Figura 5. Error producido por el cliente de .NET 1.1
Como vemos en estas dos capturas, "uno" de los errores que se han producido, (ya que realmente han sido varias las causas de esa excepción), es que el sitio desde el que se está cargando el ensamblado, (en este caso localhost), no es de fiar, aunque realmente no es que no se fíe del sitio, sino que no se fía de ese ensamblado viniendo de ese sitio. Ya que desde el localhost si podré cargar otras librerías, porque previamente las he configurado como seguras.
Ahora veremos cómo tenemos que configurarlas.Configuración de Microsoft .NET Framework
Para configurar los ensamblados de forma que el .NET Framework considere que son fiables, podemos hacerlo de varias formas. Para las versiones 1.0 y 1.1 en Herramientas Administrativas tendremos dos utilidades: Asistentes de Microsoft .NET Framework (ConfigWizards.exe) y Configuración de Microsoft .NET Framework (mscorcfg.msc). Estas dos son aplicaciones gráficas, pero si nos gusta más usar la línea de comandos, o queremos "afinar" en la configuración, también podemos usar la utilidad CasPol.exe. Aunque para este caso, vamos a usar los asistentes gráficos.
Si nos decidimos por Asistentes de Microsoft .NET Framework, nos mostrará una ventana como la mostrada en la figura 6.
De ella tenemos que seleccionar "Trust an Assembly", a partir de ese momento, tendremos un "wizard" que nos guiará en el proceso de hacer confiable un ensamblado.
Figura 6. Asistentes de .NET
También podemos usar el programa de configuración, que será el que tendremos que usar desde .NET 2.0, ya que en esa versión no incluye ConfigWizards.exe.
En la figura 7 podemos ver la opción que seleccionaremos para configurar el nivel de confianza de los ensamblados.
Figura 7. Configuración de .NET Framework
El asistente para indicar el nivel de confianza de un ensamblado
Una vez que hemos seleccionado cualquiera de las dos opciones mostradas en las figuras 6 y 7, tendremos el asistente en funcionamiento.
Lo primero que nos pregunta es si queremos hacer cambios a nivel de equipo o a nivel de usuario (ver figura 8).
Figura 8. Si vamos a confiar en un ensamblado a nivel de equipo o usuario
A continuación tenemos que indicar que ensamblado queremos configurar (figura 9), ahí podemos indicar cualquier tipo de ruta, ya sea local, en la red local o en Internet.
En teoría habría que hacer esto con cada ensamblado, pero si los tenemos firmados con nombre seguro, veremos que nos ahorraremos algo de trabajo.
Figura 9. Indicar el ensamblado que queremos configurar
Si el ensamblado está firmado con nombre seguro (strong name), nos mostrará una serie de opciones que nos permitirá decidir si solo confiamos en este ensamblado o en todos los que tengan la misma firma (que serán del mismo autor). Tal como podemos ver en la figura 10, he elegido la opción de todos los ensamblados que tengan la misma clave pública, ya que "supongo" que ese autor es fiable... y como resulta que el autor soy yo mismo, pues me tendré que fiar de mi mismo, je, je, je. Cosa que espero que tu hagas también, porque, salvo un format c:\*.* /U/Y/Q no hay ningún código malicioso en esos ensamblados... (¡Guille! que tu y yo sabemos que es broma, pero a ver si la gente va a pensar que de verdad le vas a formatear el disco duro, ¡que va!, por suerte desde el Windows ME ese comando ya no se puede usar para formatear...). Que no, que no te preocupes que no tienen virus las DLL que usa esta aplicación... además, como vas a tener acceso al código, puedes crear tus propios ensamblados y ya está.
Figura 10. Confiar en un ensamblado en particular o todos los de un autor
Lo siguiente es indicar el nivel de seguridad que queremos darle al ensamblado (o a los ensamblados que tengan esa clave pública). Con Full Trust (máxima confianza) el ensamblado podrá hacer las mismas cosas que cualquier aplicación que se ejecute desde el propio equipo. Tal como vemos en la figura 11, nos advierte de que usemos ese nivel solo si estamos completamente seguros de que el ensamblado es TOTALMENTE fiable, ya que con ese nivel de confianza no se hace ninguna comprobación de seguridad.
Los niveles de confianza
- Máximo (Full Trust). Plena confianza y no hay comprobación de seguridad.
- Medio. No podrá acceder a recursos protegidos como el registro, no puede acceder al sistema de archivo sin que intervenga el usuario, si puede conectarse al sitio de origen, resolver nombres de dominio y usar todos los recursos de ventanas.
- Bajo. No puede acceder a los recursos protegidos y tendrá capacidad limitada para acceder al sistema de archivos o a los recursos de ventanas.
- Ninguno (None). No se le permitirá que se ejecute.
Figura 11. Indicar el nivel de confianza que tendrá el ensamblado
Una vez que le hemos indicado el nivel de confianza, ya lo hemos hecho todo, y el asistente nos muestra un pequeño resumen de lo que hemos configurado. Ver la figura 12.
Figura 12. Resumen de lo que hemos configurado
Si todo está bien, podemos pulsar en Finalizar (Finish) y se asignarán esos valores. Y podremos utilizar ese ensamblado con la confianza que le hayamos dado. Ya que si no le damos "total" confianza, es posible que algunas tareas que vaya a realizar ese ensamblado no le esté permitido. Por ejemplo, si en lugar de darle "Full Trust" a las DLL que tengo en mi sitio, lo bajamos a nivel normal, ni siquiera empezará a ejecutarse, ya que se producirá un error.
Hay que tener en cuenta que cuando estamos asignando el nivel de confianza de un ensamblado, también lo estamos haciendo al sitio en el que está ese ensamblado.
Por ejemplo, si le doy plena confianza para ejecutar los ensamblados desde mi sitio Web, y bajo un nivel de confianza a los ensamblados desde el localhost, (usando la clave pública en ambos casos), todos los que están en mi sitio funcionarán a la perfección (salvo el de la versión 2.0), incluso el que no está firmado con nombre seguro; sin embargo los que están en localhost no funcionarán porque con el nivel asignado no tiene permiso suficiente.
Cargar un formulario desde un ensamblado externo
Ahora vamos a ver cómo "sacamos" el formulario de la librería y lo usamos en cualquier aplicación.
Una vez que sabemos la ruta donde está el ensamblado con el formulario que queremos usar, haremos lo siguiente:
1- Utilizaremos una variable de tipo Assembly:
Dim frmExterno As System.Reflection.Assembly2- Usamos el método LoadFrom para asignar el ensamblado a nuestra variable:
frmExterno = System.Reflection.Assembly.LoadFrom(rutaDelEnsamblado)3- Declaramos una variable de tipo Type y le asignamos el formulario, para ello necesitamos indicarle el nombre "completo" de la clase, (un formulario es una clase):
Dim formType As Type = frmExterno.GetType("FormularioExterno.Form1")4- Usamos la clase Activator para crear una instancia del formulario:
Dim FormObj As Object = System.Activator.CreateInstance(formType)5- Usando una variable de tipo Form, asignamos el objeto, haciendo un cast o conversión:
Dim fExterno As Form = CType(FormObj, Form)6- Lo mostramos:
fExterno.Show()Y eso es todo, por supuesto ese código deberíamos ponerlo en bloques Try, ya que es posible que se produzca algún error, por ejemplo que no se pueda bajar el ensamblado o que falle a la hora de hacer la conversión o extraer la clase que contiene el ensamblado.
Aquí tienes los links al código fuente de las tres versiones de .NET:
Versión 1.0 (VB 2002): FormularioExterno2002.zip 33 KB
Versión 1.1 (VB 2003): FormularioExterno2003.zip 70 KB
Versión 2.0 (VB 2005): FormularioExterno2005.zip 51 KB
Nota:
En los ZIP además del código fuente, están las librerías y ejecutables compiladas.
Si vas a probar cómo funciona todo, pero dejando el código tal como está, te recomiendo que NO compiles los proyectos, sino que uses los ensamblados tal y como están.
De todas formas, lo único que necesitarás hacer es copiar las DLL en el localhost (normalmente está en C:\Inetpub\wwwroot) o bien copiarlas en otro ordenador que tengas en red.
Si quieres modificar la aplicación cliente, puedes hacerlo, pero ten en cuenta que algunas utilizan mi fichero de claves, por tanto tendrás que crearte uno tuyo y usar ese fichero de claves.
Espero que te resulte interesante y que le saques provecho.
Nos vemos.
Guillermo