Diferencias principales entre IIS y el Servidor de desarrollo de ASP.NET (C#)

por Scott Mitchell

Descargar PDF

Al probar una aplicación ASP.NET localmente, es probable que use el servidor web de desarrollo de ASP.NET. Sin embargo, es más probable que el sitio web de producción sea IIS con tecnología. Existen algunas diferencias entre la forma en que estos servidores web controlan las solicitudes y estas diferencias pueden tener consecuencias importantes. En este tutorial se exploran algunas de las diferencias más importantes.

Introducción

Cada vez que un usuario visita una aplicación ASP.NET su navegador envía una solicitud al sitio web. El software del servidor web recoge esa solicitud, que se coordina con el runtime de ASP.NET para generar y devolver el contenido del recurso solicitado. I nternet I nformation S ervices (IIS) es un conjunto de servicios que proporcionan una funcionalidad común basada en Internet para servidores Windows. IIS es el servidor web más usado para aplicaciones ASP.NET en entornos de producción; lo más probable es que el proveedor de host web use el software de servidor web para atender la aplicación ASP.NET. IIS también se puede usar como software de servidor web en el entorno de desarrollo, aunque esto implica instalar IIS y configurarlo correctamente.

El servidor de desarrollo de ASP.NET es una opción alternativa de servidor web para el entorno de desarrollo; se distribuye con y se integra en Visual Studio. A menos que la aplicación web se haya configurado para usar IIS, el servidor de desarrollo de ASP.NET se inicia automáticamente y se usa como servidor web la primera vez que visite una página web desde Visual Studio. Las aplicaciones web de demostración que creamos de nuevo en el tutorial Determinar qué archivos deben implementarse eran aplicaciones web basadas en el sistema de archivos que no estaban configuradas para usar IIS. Por lo tanto, al visitar cualquiera de estos sitios web desde Visual Studio, se usa el servidor de desarrollo de ASP.NET.

En un mundo perfecto, los entornos de desarrollo y producción serían idénticos. Sin embargo, como se explicó en el tutorial anterior, no es raro que los entornos tengan valores de configuración diferentes. El uso de un software de servidor web diferente en los entornos agrega otra variable que se debe tener en cuenta al implementar una aplicación. En este tutorial se tratan las principales diferencias entre IIS y el servidor de desarrollo de ASP.NET. Debido a estas diferencias, hay escenarios en los que el código que se ejecuta sin errores en el entorno de desarrollo produce una excepción o se comporta de forma diferente cuando se ejecuta en producción.

Diferencias de contexto de seguridad

Cada vez que el software del servidor web controla una solicitud entrante, asocia esa solicitud a un contexto de seguridad determinado. El sistema operativo usa esta información de contexto de seguridad para determinar qué acciones permite la solicitud. Por ejemplo, una página ASP.NET podría incluir código que registra algún mensaje en un archivo en el disco. Para que esta página ASP.NET se ejecute sin errores, el contexto de seguridad debe tener los permisos de nivel de sistema de archivos adecuados, es decir, permisos de escritura en ese archivo.

El servidor de desarrollo de ASP.NET asocia las solicitudes entrantes con el contexto de seguridad del usuario que ha iniciado sesión actualmente. Si ha iniciado sesión en el escritorio como administrador, las páginas ASP.NET atendidas por el servidor de desarrollo de ASP.NET tendrán los mismos derechos de acceso que un administrador. Sin embargo, las solicitudes ASP.NET controladas por IIS están asociadas a una cuenta de máquina específica. De forma predeterminada, la cuenta del equipo de servicio de red la usan las versiones 6 y 7 de IIS, aunque el proveedor de host web puede haber configurado una cuenta única para cada cliente. Además, es probable que el proveedor de host web haya concedido permisos limitados a esta cuenta de máquina. El resultado neto es que puede tener páginas web que se ejecutan sin errores en el entorno de desarrollo, pero generar excepciones relacionadas con la autorización cuando se hospedan en el entorno de producción.

Para mostrar este tipo de error en acción, he creado una página en el sitio web de reseñas de libros que crea un archivo en el disco que almacena la fecha y hora más recientes en las que alguien ha visto la reseña de Teach Yourself ASP.NET 3.5 in 24 Hours. Para continuar, abra la página ~/Tech/TYASP35.aspx y agregue el siguiente código al controlador de eventos Page_Load:

protected void  Page_Load(object sender, EventArgs e)

{

    string filePath =  Server.MapPath("~/LastTYASP35Access.txt");

    string contents =  string.Format("Last accessed on {0} by {1}",

        DateTime.Now.ToString(), Request.UserHostAddress);

    System.IO.File.WriteAllText(filePath,  contents);

}

Nota:

El método File.WriteAllText crea un nuevo archivo si no existe y, a continuación, escribe el contenido especificado en él. Si el archivo ya existe, se sobrescribe el contenido existente.

A continuación, visite la página de la reseña del libro Teach Yourself ASP.NET 3.5 in 24 Hours en el entorno de desarrollo mediante el servidor de desarrollo de ASP.NET. Suponiendo que haya iniciado sesión en el equipo con una cuenta que tenga los permisos adecuados para crear y modificar un archivo de texto en el directorio raíz de la aplicación web, la reseña del libro aparece igual que antes, pero, cada vez que la página se visita, la fecha y hora y la dirección IP del usuario se almacena en el archivo LastTYASP35Access.txt. Apunte su explorador a este archivo; debería ver un mensaje similar al que se muestra en la ilustración 1.

The Text File Contains the Last Date and Time the Book Review was Visited

Ilustración 1: el archivo de texto contiene la última fecha y hora en que se visitó la reseña del libro (haga clic para ver la imagen a tamaño completo)

Implemente la aplicación web en producción y, a continuación, visite la página de revisión del libro hospedado Teach Yourself ASP.NET 3.5 in 24 Hours. En este momento, debería ver la página de revisión del libro de forma normal o el mensaje de error que se muestra en la ilustración 2. Algunos proveedores de host web conceden permisos de escritura a la cuenta de máquina de ASP.NET anónima, en cuyo caso la página funcionará sin errores. Sin embargo, si el proveedor de host web prohíbe el acceso de escritura para la cuenta anónima, se genera una excepción UnauthorizedAccessException cuando la página TYASP35.aspx intenta escribir la fecha y hora actuales en el archivo LastTYASP35Access.txt.

The Default Machine Account Used by IIS Does Not Have Permissions to Write to the File System

Ilustración 2: la cuenta de máquina predeterminada usada por IIS no tiene permisos para escribir en el sistema de archivos (haga clic para ver la imagen a tamaño completo)

La buena noticia es que la mayoría de los proveedores de host web tienen algún tipo de herramienta de permisos que le permite especificar permisos del sistema de archivos en su sitio web. Conceda a la cuenta de ASP.NET anónima acceso de escritura al directorio raíz y, a continuación, vuelva a visitar la página de reseña del libro. (Si es necesario, póngase en contacto con el proveedor de host web para obtener ayuda sobre cómo conceder permisos de escritura a la cuenta de ASP.NET predeterminada). Esta vez la página debe cargarse sin errores y el archivo LastTYASP35Access.txt se debe crear correctamente.

La conclusión es que debido a que el servidor de desarrollo ASP.NET opera bajo un contexto de seguridad diferente al de IIS, es posible que sus páginas ASP.NET que leen o escriben en el sistema de archivos, leen o escriben en el registro de eventos de Windows, o leen o escriben en el registro de Windows funcionen como se espera en desarrollo pero generen excepciones cuando estén en producción. Al compilar una aplicación web que se implementará en un entorno de hospedaje web compartido, no lea ni escriba en el registro de eventos ni en el registro de Windows. Tome nota también de las páginas ASP.NET que leen o escriben en el sistema de archivos, ya que es posible que tenga que conceder privilegios de lectura y escritura en las carpetas adecuadas del entorno de producción.

Diferencias en el servicio de contenido estático

Otra diferencia principal entre IIS y el servidor de desarrollo de ASP.NET es cómo administran las solicitudes de contenido estático. Cada solicitud que entra en el servidor de desarrollo de ASP.NET, ya sea para una página ASP.NET, una imagen o un archivo JavaScript, se procesa mediante el runtime de ASP.NET. De forma predeterminada, IIS solo invoca el runtime de ASP.NET cuando una solicitud entra en un recurso de ASP.NET, como una página web de ASP.NET, un servicio web, etc. Las solicitudes de contenido estático (imágenes, archivos CSS, archivos JavaScript, archivos PDF, archivos ZIP y similares) se recuperan mediante IIS sin la intervención del runtime de ASP.NET. (Es posible indicar a IIS que funcione con el runtime de ASP.NET al proporcionar contenido estático; consulte la sección "Realización de la autenticación basada en formularios y la autenticación de direcciones URL en archivos estáticos con IIS 7" en este tutorial para obtener más información).

El runtime de ASP.NET realiza una serie de pasos para generar el contenido solicitado, incluida la autenticación (identificación del solicitante) y la autorización (determinar si el solicitante tiene permiso para ver el contenido solicitado). Una forma popular de autenticación es la autenticación basada en formularios, en la que un usuario se identifica escribiendo sus credenciales (normalmente un nombre de usuario y una contraseña) en cuadros de texto de una página web. Al validar sus credenciales, el sitio web almacena una cookie de vale de autenticación en el explorador del usuario, que se envía con cada solicitud posterior al sitio web y es lo que se usa para autenticar al usuario. Además, es posible especificar reglas de autorización de direcciones URL que dictan lo que los usuarios pueden o no pueden acceder a una carpeta determinada. Muchos sitios web ASP.NET usan la autenticación basada en formularios y la autorización de direcciones URL para admitir cuentas de usuario y definir partes del sitio que solo son accesibles para usuarios autenticados o usuarios que pertenecen a un determinado rol.

Nota:

Si desea un examen exhaustivo de la autenticación basada en formularios de ASP.NET, la autorización de URL y otras funciones relacionadas con las cuentas de usuario, no deje de consultar mis Tutoriales de seguridad de sitios web.

Considere un sitio web que admita cuentas de usuario mediante la autorización basada en formularios y tenga una carpeta que, mediante autorización de dirección URL, esté configurada para permitir solo a los usuarios autenticados. Imagine que esta carpeta contiene páginas ASP.NET y archivos PDF y que la intención es que solo los usuarios autenticados puedan ver estos archivos PDF.

¿Qué ocurre si un visitante intenta ver uno de estos archivos PDF escribiendo la dirección URL directamente en la barra de direcciones de su explorador? Para averiguarlo, vamos a crear una carpeta en el sitio de reseñas de libros, agregar algunos archivos PDF y configurar el sitio para usar la autorización de dirección URL para prohibir que los usuarios anónimos visiten esta carpeta. Si descarga la aplicación de demostración, verá que he creado una carpeta denominada PrivateDocs y he añadido un PDF de mis Tutoriales de seguridad de sitios web (¡qué bien!). La carpeta PrivateDocs también contiene un archivo Web.config que especifica las reglas de autorización de dirección URL para denegar a los usuarios anónimos:

<?xml version="1.0"?>
<?xml version="1.0"?>

<configuration>

    <system.web>

         <authorization>

            <deny  users="?" />

         </authorization>

     </system.web>

</configuration>

Por último, configuré la aplicación web para que use la autenticación basada en formularios mediante la actualización del archivo Web.config en el directorio raíz, reemplazando:

<authentication mode="Windows" />

Por:

<authentication mode="Forms" />

Con el servidor de desarrollo de ASP.NET, visite el sitio y escriba la dirección URL directa a uno de los archivos PDF en la barra de direcciones del explorador. Si descargó el sitio web asociado a este tutorial, la dirección URL debería tener un aspecto similar al siguiente: http://localhost:portNumber/PrivateDocs/aspnet_tutorial01_Basics_vb.pdf

Al escribir esta dirección URL en la barra de direcciones, el explorador envía una solicitud al servidor de desarrollo de ASP.NET para el archivo. El servidor de desarrollo de ASP.NET entrega la solicitud al runtime de ASP.NET para su procesamiento. Dado que aún no hemos iniciado sesión y porque el Web.config de la carpeta PrivateDocs está configurado para denegar el acceso anónimo, el runtime de ASP.NET nos redirige automáticamente a la página de inicio de sesión, Login.aspx (véase la ilustración 3). Al redirigir al usuario a la página de inicio de sesión, ASP.NET incluye un parámetro querystring ReturnUrl que indica la página que el usuario estaba intentando ver. Después de iniciar sesión correctamente en el usuario, se puede devolver a esta página.

Unauthorized Users are Automatically Redirected to the Login Page

Ilustración 3: los usuarios no autorizados se redirigen automáticamente a la página de inicio de sesión (haga clic para ver la imagen a tamaño completo)

Ahora veamos cómo se comporta esto en producción. Implemente la aplicación y escriba la dirección URL directa en uno de los archivos PDF de la carpeta PrivateDocs en producción. Esto solicita al explorador que envíe una solicitud IIS para el archivo. Dado que se solicita un archivo estático, IIS recupera y devuelve el archivo sin invocar el runtime de ASP.NET. Como resultado, no se realizó ninguna comprobación de autorización de dirección URL; el contenido del PDF supuestamente privado es accesible para cualquier persona que conozca la dirección URL directa del archivo.

Anonymous Users Can Download the Private PDF Files By Entering the Direct URL to the File

Ilustración 4: los usuarios anónimos pueden descargar los archivos PDF privados escribiendo la dirección URL directa al archivo (haga clic para ver la imagen a tamaño completo)

Realización de la autenticación basada en formularios y la autenticación de direcciones URL en archivos estáticos con IIS 7

Hay un par de técnicas que puede usar para proteger el contenido estático de usuarios no autorizados. IIS 7 introdujo la canalización integrada, que se casa con el flujo de trabajo de IIS con el flujo de trabajo del runtime de ASP.NET. En pocas palabras, puede indicar a IIS que invoque los módulos de autenticación y autorización del runtime de ASP.NET en todas las solicitudes entrantes (incluido el contenido estático, como los archivos PDF). Póngase en contacto con el proveedor de host web para averiguar cómo configurar el sitio web para usar la canalización integrada.

Una vez configurado IIS para usar la canalización integrada, agregue el marcado siguiente al archivo Web.config en el directorio raíz:

<system.webServer>

      <modules>

          <add  name="FormsAuthenticationModule"  type="System.Web.Security.FormsAuthenticationModule" />

          <remove  name="UrlAuthorization" />

          <add  name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule"  />

          <remove  name="DefaultAuthentication" />

          <add  name="DefaultAuthentication"  type="System.Web.Security.DefaultAuthenticationModule" />

      </modules>

</system.webServer>

Este marcado indica a IIS 7 que use los módulos de autenticación y autorización basados en ASP.NET. Vuelva a implementar la aplicación y vuelva a visitar el archivo PDF. Esta vez, cuando IIS gestiona la solicitud, da a la lógica de autenticación y autorización de ASP.NET la oportunidad de inspeccionar la solicitud. Dado que solo los usuarios autenticados están autorizados para ver el contenido en la carpeta PrivateDocs, el visitante anónimo se redirige automáticamente a la página de inicio de sesión (véase la ilustración 3).

Nota:

Si el proveedor de host web sigue usando IIS 6, no puede usar la característica de canalización integrada. Una solución consiste en colocar los documentos privados en una carpeta que prohíbe el acceso HTTP (por ejemplo, App_Data) y, a continuación, crear una página para atender estos documentos. Esta página puede llamarse GetPDF.aspx, y se pasa el nombre del PDF a través de un parámetro querystring. La página GetPDF.aspx comprobaría primero que el usuario tiene permiso para ver el archivo y, si es así, usaría el método Response.WriteFile(filePath) para devolver el contenido del archivo PDF solicitado al cliente solicitante. Esta técnica también funcionaría para IIS 7 si no desea habilitar la canalización integrada.

Resumen

Las aplicaciones web de un entorno de producción se hospedan mediante el software de servidor web IIS de Microsoft. Sin embargo, en el entorno de desarrollo, la aplicación se puede hospedar mediante IIS o el servidor de desarrollo de ASP.NET. Lo ideal sería usar el mismo software de servidor web en ambos entornos porque el uso de software diferente agrega otra variable en la combinación. Sin embargo, la facilidad de uso del servidor de desarrollo de ASP.NET hace que sea una opción atractiva en el entorno de desarrollo. La buena noticia es que solo hay algunas diferencias importantes entre IIS y el servidor de desarrollo de ASP.NET, y si conoce estas diferencias, puede tomar medidas para ayudar a garantizar que la aplicación funciona y funciona de la misma manera independientemente del entorno.

¡Feliz programación!

Lecturas adicionales

Para obtener más información sobre los temas tratados en este tutorial, consulte los siguientes recursos: