Agregar seguridad y pertenencia a un sitio de ASP.NET Web Pages (Razor)

de Tom FitzMacken

En este artículo se explica cómo proteger un sitio web de ASP.NET Web Pages (Razor) para que algunas de las páginas solo estén disponibles para las personas que inician sesión. (También verá cómo crear páginas a las que cualquier usuario pueda acceder).

Aprenderá lo siguiente:

  • Cómo crear un sitio web que tenga una página de registro y una página de inicio de sesión para que en algunas páginas pueda limitar el acceso solo a los miembros.
  • Cómo crear páginas públicas y solo para miembros.
  • Cómo definir roles, que son grupos que tienen permisos de seguridad diferentes en el sitio, y cómo asignar usuarios a un rol.
  • Cómo usar CAPTCHA para evitar que los programas automatizados (bots) creen cuentas de miembro.

Estas son las características de ASP.NET presentadas en el artículo:

  • La plantilla Sitio de inicio de WebMatrix.
  • El asistente WebSecurity y la clase Roles.
  • El asistente ReCaptcha.

Versiones de software usadas en el tutorial

  • ASP.NET Web Pages (Razor) 2
  • WebMatrix 3
  • Biblioteca de asistentes web de ASP.NET

Puede configurar su sitio web para que los usuarios puedan iniciar sesión en él, es decir, para que el sitio admita la pertenencia. Esto puede ser útil por muchas razones. Por ejemplo, el sitio podría tener páginas que solo deberían estar disponibles para los miembros. En algunos casos, es posible que necesite que los usuarios inicien sesión para enviarle o dejar un comentario.

Incluso si su sitio web admite la pertenencia, los usuarios no necesariamente deben iniciar sesión si no usan algunas de las páginas del sitio. Los usuarios que no han iniciado sesión se conocen como usuarios anónimos.

Un usuario puede registrarse en el sitio web y, a continuación, iniciar sesión en el sitio. El sitio web requiere un nombre de usuario (una dirección de correo electrónico) y una contraseña para confirmar que los usuarios son quienes dicen ser. Este proceso de inicio de sesión y confirmación de la identidad de un usuario se conoce como autenticación.

Puede configurar la seguridad y la pertenencia de diferentes maneras:

  • Si usa WebMatrix, una manera sencilla es crear un nuevo sitio basado en la plantilla Sitio de inicio. Esta plantilla ya está configurada para seguridad y pertenencia y ya tiene una página de registro, una página de inicio de sesión, etc.

    El sitio creado por la plantilla también tiene una opción para permitir que los usuarios inicien sesión desde un sitio externo, como Facebook, Google o Twitter.

  • Si desea agregar seguridad a un sitio existente o si no quiere usar la plantilla Sitio de inicio, puede crear su propia página de registro, página de inicio de sesión, etc.

Este artículo se centra en la primera opción: cómo agregar seguridad mediante la plantilla Sitio de inicio. También proporciona información básica sobre cómo implementar su propia seguridad y, a continuación, proporciona vínculos a más información sobre cómo hacerlo. También hay información sobre cómo habilitar inicios de sesión externos, que se describen con más detalle en un artículo independiente.

Crear seguridad de sitio web mediante la plantilla Sitio de inicio

En WebMatrix puede usar la plantilla Sitio de inicio para crear un sitio web que contenga lo siguiente:

  • Una base de datos que se usa para almacenar nombres de usuario y contraseñas para los miembros.
  • Una página de registro en la que los usuarios anónimos (nuevos) pueden registrarse.
  • Una página de inicio de sesión y cierre de sesión.
  • Una página de recuperación y restablecimiento de contraseñas.

En el procedimiento siguiente se describe cómo crear el sitio y configurarlo.

  1. Inicie WebMatrix y, en la página Inicio rápido, seleccione Sitio desde plantilla.

  2. Seleccione la plantilla Sitio de inicio y haga clic en Aceptar. WebMatrix crea un nuevo sitio.

  3. En el panel izquierdo, haga clic en el selector del área de trabajo Archivos.

  4. En la carpeta raíz de su sitio web, abra el archivo _AppStart.cshtml, que es un archivo especial que se usa para contener la configuración global. Contiene algunas instrucciones que se comentan con los caracteres //:

    //WebMail.SmtpServer = "mailserver.example.com";
    //WebMail.EnableSsl = true;
    //WebMail.UserName = "username@example.com";
    //WebMail.Password = "your-password";
    //WebMail.From = "your-name-here@example.com";
    

    Estas instrucciones configuran el asistente WebMail, que se puede usar para enviar correo electrónico. El sistema de pertenencia puede usar el correo electrónico para enviar mensajes de confirmación cuando los usuarios se registren o cuando quieran cambiar sus contraseñas. (Por ejemplo, después de que los usuarios se registren, obtienen un correo electrónico que incluye un vínculo en el que pueden hacer clic para finalizar el proceso de registro).

    El envío de correo electrónico requiere acceso a un servidor SMTP, como se describe en Agregar correo electrónico a un sitio de ASP.NET Web Pages. Almacenará la configuración de correo electrónico en este archivo central _AppStart.cshtml para que no tenga que codificarlos repetidamente en cada página que pueda enviar correo electrónico. (No es necesario configurar las valores SMTP para configurar una base de datos de registro; solo necesita valores SMTP si desea validar a los usuarios desde su alias de correo electrónico y permitir que los usuarios restablezcan una contraseña olvidada).

  5. Quite la marca de comentario de las instrucciones quitando // de delante de cada una.

    Si no desea configurar la confirmación de correo electrónico puede omitir este paso y el paso siguiente. Si no se establecen los valores SMTP, la nueva cuenta estará disponible inmediatamente sin un correo electrónico de confirmación.

  6. Modifique la siguiente configuración relacionada con el correo electrónico en el código:

    • Establezca WebMail.SmtpServer en el nombre del servidor SMTP al que tiene acceso.

    • Deje WebMail.EnableSsl establecido en true. Esta configuración protege las credenciales que se envían al servidor SMTP mediante su cifrado.

    • Establezca WebMail.UserName en el nombre de usuario de la cuenta del servidor SMTP.

    • Establezca WebMail.Password en la contraseña de la cuenta del servidor SMTP.

    • Establezca WebMail.From en su propia dirección de correo electrónico. Es la dirección de correo electrónico desde la que se envía el mensaje.

      Nota:

      Sugerencia Para obtener información adicional sobre los valores de estas propiedades, vea Configurar la configuración de correo electrónico en Personalizar el comportamiento de todo el sitio para ASP.NET Web Pages.

  7. Guarde y cierre _AppStart.cshtml.

  8. Ejecute la página Default.cshtml en un explorador.

    security-membership-2

    Nota:

    Si ve un error que indica que una propiedad debe ser una instancia de ExtendedMembershipProvider, es posible que el sitio no esté configurado para usar el sistema de pertenencia de ASP.NET Web Pages (SimpleMembership). Esto puede ocurrir a veces si el servidor de un proveedor de hospedaje está configurado de forma diferente al servidor local. Para corregirlo, agregue el siguiente elemento al archivo Web.config del sitio:

    <appSettings>
        <add key="enableSimpleMembership" value="true" />
    </appSettings>
    

    Agregue este elemento como elemento secundario del elemento <configuration> y como un elemento del mismo nivel del elemento <system.web>.

  9. En la esquina superior derecha de la página, haga clic en el vínculo Registro. Se muestra la página Register.cshtml.

  10. Escriba un nuevo nombre de usuario y una contraseña y, a continuación, haga clic en Registro.

    security-membership-3

    Cuando creó el sitio web a partir de la plantilla Sitio de inicio, se creó una base de datos denominada StarterSite.sdf en la carpeta App_Data del sitio. Durante el registro, la información del usuario se agrega a la base de datos. Si establece los valores SMTP, se envía un mensaje a la dirección de correo electrónico que usó para que pueda terminar de registrarse.

    security-membership-4

  11. Vaya al programa de correo electrónico y busque el mensaje, que tendrá el código de confirmación y un hipervínculo al sitio.

  12. Haga clic en el hipervínculo para activar la cuenta. El hipervínculo de confirmación abre una página de confirmación de registro.

    security-membership-5

  13. Haga clic en el vínculo de Inicio de sesión y, a continuación, inicie sesión con la cuenta que registró.

    Después de iniciar sesión, los vínculos de Inicio de sesión y Registro se reemplazan por un vínculo de Cierre de sesión. El nombre de inicio de sesión se muestra como un vínculo. (El vínculo le permite ir a una página donde puede cambiar la contraseña).

    security-membership-6

    Nota:

    De forma predeterminada, las páginas web de ASP.NET envían credenciales al servidor en texto no cifrado (como texto legible para humanos). Un sitio de producción debe usar HTTP seguro (https://, también conocido como capa de sockets seguros o SSL) para cifrar información confidencial que se intercambia con el servidor. Puede requerir que los mensajes de correo electrónico se envíen mediante SSL estableciendo WebMail.EnableSsl=true como en el ejemplo anterior. Para obtener más información sobre SSL, consulte Proteger las comunicaciones web: certificados, SSL y https://.

Funcionalidad de pertenencia adicional en el sitio

El sitio contiene otras funciones que permiten a los usuarios administrar sus cuentas. Los usuarios pueden hacer lo siguiente:

  • Cambiar sus contraseñas. Después de iniciar sesión, pueden hacer clic en el nombre de usuario (que es un vínculo). Esto los lleva a una página donde pueden crear una nueva contraseña (Account/ChangePassword.cshtml).
  • Recuperar una contraseña olvidada. En la página de inicio de sesión hay un vínculo (¿Olvidó la contraseña?) que lleva a los usuarios a una página (Account/ForgotPassword.cshtml), donde pueden escribir una dirección de correo electrónico. El sitio les envía un mensaje de correo electrónico que tiene un vínculo en el que pueden hacer clic para establecer una nueva contraseña (Account/PasswordReset.cshtml).

También puede permitir que los usuarios también puedan iniciar sesión desde un sitio externo, como se explica más adelante.

Crear una página solo para miembros

Por el momento, cualquier persona puede navegar por cualquier página de su sitio web. Pero es posible que quiera tener páginas que solo estén disponibles para las personas que han iniciado sesión (es decir, para los miembros). ASP.NET le permite crear páginas a las que solo pueden acceder los miembros que han iniciado sesión. Normalmente, si los usuarios anónimos intentan acceder a una página de solo miembros, los redirigirá a la página de inicio de sesión.

En este procedimiento creará una carpeta que contendrá páginas que solo están disponibles para los usuarios que han iniciado sesión.

  1. En la raíz del sitio, cree una nueva carpeta. (En la cinta de opciones, haga clic en la flecha debajo de Nuevo y, a continuación, elija Nueva carpeta).

  2. Asigne a la nueva carpeta el nombre Miembros.

  3. Dentro de la carpeta Miembros, cree una nueva página y asígnele el nombre MembersInformation.cshtml.

  4. Reemplace el contenido existente por el código y el marcado siguientes:

    @{
        if (!WebSecurity.IsAuthenticated) {
            Response.Redirect("~/Account/Login?returnUrl="
                + Request.Url.LocalPath);
        }
        Layout = "~/_SiteLayout.cshtml";
        Page.Title = "Members Information";
    }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>Members Information</title>
      </head>
      <body>
        <p>You can only see this information if you've logged into the site.</p>
      </body>
    </html>
    

    Este código prueba la propiedad IsAuthenticated del objeto WebSecurity, que devuelve true si el usuario ha iniciado sesión. Si el usuario no ha iniciado sesión, el código llama a Response.Redirect para enviar al usuario a la página Login.cshtml de la carpeta Cuenta.

    La dirección URL del redireccionamiento incluye un valor de cadena de consulta returnUrl que usa Request.Url.LocalPath para establecer la ruta de acceso de la página actual. Si establece el valor returnUrl en la cadena de consulta así (y si la dirección URL de retorno es una ruta de acceso local), la página de inicio de sesión devolverá a los usuarios a esta página después de iniciar sesión.

    El código también establece la página _SiteLayout.cshtml como página de diseño. (Para obtener más información sobre las páginas de diseño, consulte Crear un diseño coherente en sitios de ASP.NET Web Pages).

  5. Ejecute el sitio. Si todavía tiene iniciada la sesión, haga clic en el botón Cerrar sesión en la parte superior de la página.

  6. En el explorador, solicite la página /Members/MembersInformation. Por ejemplo, la dirección URL podría tener este aspecto:

    http://localhost:38366/Members/MembersInformation

    (El número de puerto (38366) probablemente será diferente en la dirección URL).

    Se le redirigirá a la página Login.cshtml, porque no ha iniciado sesión.

  7. Inicie sesión con la cuenta que creó anteriormente. Se le redirige de vuelta a la página MembersInformation. Dado que ha iniciado sesión, esta vez verá el contenido de la página.

Para proteger el acceso a varias páginas, puede hacer esto:

  • Agregue la comprobación de seguridad a cada página.
  • Cree una página _PageStart.cshtml en la carpeta donde mantiene páginas protegidas y agregue la comprobación de seguridad allí. La página _PageStart.cshtml actúa como un especie de página global para todas las páginas de la carpeta. Esta técnica se explica con más detalle en Personalizar el comportamiento de todo el sitio para ASP.NET Web Pages.

Crear seguridad para grupos de usuarios (roles)

Si el sitio tiene muchos miembros, no es eficaz comprobar el permiso de cada usuario individualmente antes de permitirle ver una página. Lo que puede hacer en su lugar es crear grupos o roles a los que pertenecen los miembros individuales. A continuación, puede comprobar los permisos en función del rol. En esta sección creará un rol "admin" y, a continuación, creará una página accesible a los usuarios que están en (que pertenecen a) ese rol.

El sistema de pertenencia de ASP.NET está configurado para admitir roles. Sin embargo, a diferencia del registro de pertenencia y el inicio de sesión, la plantilla Sitio de inicio no contiene páginas que le ayuden a administrar roles. (Administrar roles es una tarea administrativa en lugar de una tarea de usuario). Sin embargo, puede agregar grupos directamente en la base de datos de pertenencia en WebMatrix.

  1. En WebMatrix, haga clic en el selector del área de trabajo Bases de datos.

  2. En el panel izquierdo, abra el nodo StarterSite.sdf, abra el nodo Tablas y haga doble clic en la tabla webpages_Roles.

    security-membership-7

  3. Agregue un rol denominado "admin". El campo RoleId se rellena automáticamente. (Es la clave principal y se ha establecido para que sea un campo de identificación, como se explica en Introducción a trabajar con una base de datos en sitios de ASP.NET Web Pages).

  4. Anote cuál es el valor del campo RoleId. (Si este es el primer rol que va a definir, será 1).

    security-membership-8

  5. Cierre la tabla webpages_Roles.

  6. Abra la tabla UserProfile.

  7. Anote el valor UserId de uno o varios de los usuarios de la tabla y, a continuación, cierre la tabla.

  8. Abra la tabla webpages_UserInRoles y escriba un valor UserID y RoleID en la tabla. Por ejemplo, para colocar al usuario 2 en el rol "admin", debería escribir estos valores:

    security-membership-9

  9. Cierre la tabla webpages_UsersInRoles.

    Ahora que tiene roles definidos, puede configurar una página accesible para los usuarios que están en ese rol.

  10. En la carpeta raíz del sitio web, cree una nueva página denominada AdminError.cshtml y reemplace el contenido existente por el código siguiente. Esta será la página a la que se redirige a los usuarios si no tienen permiso para acceder a una página.

    @{
        Layout = "~/_SiteLayout.cshtml";
        PageData["Title"] = "Admin-only Error";
    }
    <p>You must log in as an admin to access that page.</p>
    
  11. En la carpeta raíz del sitio web, cree una nueva página denominada AdminOnly.cshtml y reemplace el código existente por el código siguiente:

    @{
        Layout = "~/_SiteLayout.cshtml";
        PageData["Title"] = "Administrators only";
    }
    
    @if ( Roles.IsUserInRole("admin")) {
        <span> Welcome <b>@WebSecurity.CurrentUserName</b>! </span>
    }
    else {
         Response.Redirect("~/AdminError");
    }
    

    El método Roles.IsUserInRole devuelve true si el usuario actual es miembro del rol especificado (en este caso, el rol "admin").

  12. Ejecute Default.cshtml en un explorador, pero no inicie sesión. (Si ya ha iniciado sesión, cierre la sesión).

  13. En la barra de direcciones del explorador, agregue AdminOnly en la dirección URL. (En otras palabras, solicite el archivo AdminOnly.cshtml). Se le redirigirá a la página AdminError.cshtml, ya que actualmente no ha iniciado sesión como usuario en el rol "admin".

  14. Vuelva a Default.cshtml e inicie sesión como el usuario que agregó al rol "admin".

  15. Vaya a la página AdminOnly.cshtml. Esta vez verá la página.

Impedir que los programas automatizados se unan a su sitio web

La página de inicio de sesión no impedirá que los programas automatizados (a veces denominados robots web o bots) se registren en su sitio web. En este procedimiento se describe cómo habilitar una prueba de ReCaptcha para la página de registro.

/media/38777/ch16securitymembership-18.jpg

  1. Registre su sitio web en el servicio de ReCaptcha. Cuando haya completado el registro, obtendrá una clave pública y una clave privada.

  2. Agregue la biblioteca de asistentes web de ASP.NET a su sitio web, tal como se describe en Instalar asistentes en un sitio de ASP.NET Web Pages, si aún no lo ha hecho aún.

  3. En la carpeta Cuenta, abra el archivo denominado Register.cshtml.

  4. En el código de la parte superior de la página, busque las siguientes líneas y quite la marca de comentario quitando los caracteres de comentario //:

    if (!ReCaptcha.Validate("PRIVATE_KEY")) {
        ModelState.AddError("recaptcha", "Captcha response was not correct");
    }
    
  5. Reemplace PRIVATE_KEY por su propia clave privada de ReCaptcha.

  6. En el marcado de la página, quite los caracteres de comentario @* y *@ de las líneas siguientes en el marcado de página:

    @ReCaptcha.GetHtml("PUBLIC_KEY", theme: "white")
    @Html.ValidationMessage("recaptcha")
    
  7. Reemplace PUBLIC_KEY por la clave.

  8. Si aún no lo ha quitado, quite el elemento <div> que contiene texto que comienza por "Para habilitar la comprobación CAPTCHA...". (Quite todo el elemento <div> y su contenido).

  9. Ejecute Default.cshtml en un explorador. Si ha iniciado sesión en el sitio, haga clic en el vínculo Cerrar sesión.

  10. Haga clic en el vínculo Registro y pruebe el registro mediante la prueba CAPTCHA.

    security-membership-10

Para obtener más información sobre el asistente ReCaptcha, consulte Usar CATPCHA para evitar que los programas automatizados (bots) usen el sitio web de ASP.NET.

Permitir que los usuarios inicien sesión desde un sitio externo

La plantilla Sitio de inicio incluye código y marcado que permite a los usuarios iniciar sesión con Facebook, Windows Live, Twitter, Google o Yahoo. De forma predeterminada, esta funcionalidad no está habilitada. El procedimiento general para permitir que los usuarios inicien sesión desde estos proveedores externos es el siguiente:

  • Decida cuál de los sitios externos que desea admitir.
  • Si es necesario, vaya a ese sitio y configure una aplicación de inicio de sesión. (Por ejemplo, tienes que hacer eso para permitir inicios de sesión de Facebook).
  • En el sitio, configure el proveedor. En la mayoría de los casos solo tiene que quitar la marca de comentario del código en el archivo _AppStart.cshtml.
  • Agregue marcado a la página de registro que permita a los usuarios vincular al sitio externo para iniciar sesión. Normalmente puede copiar el marcado que necesita y cambiar el texto ligeramente.

Puede encontrar instrucciones paso a paso en el tema Habilitar el inicio de sesión desde sitios externos en un sitio de ASP.NET Web Pages.

Después de que un usuario inicie sesión desde otro sitio, el usuario vuelve al sitio y asocia ese inicio de sesión con el sitio. En efecto, esto crea una entrada de pertenencia en el sitio para el inicio de sesión externo del usuario. Esto le permite usar las funcionalidades normales de pertenencia (como roles) con el inicio de sesión externo.

Agregar seguridad a un sitio web existente

El procedimiento anterior de este artículo se basa en el uso de la plantilla Sitio de inicio como base para la seguridad del sitio web. Si no le resulta práctico empezar desde la plantilla Sitio de inicio o copiar las páginas pertinentes de un sitio basado en esa plantilla, puede implementar el mismo tipo de seguridad en su propio sitio codificando usted mismo. Cree los mismos tipos de páginas (registro, inicio de sesión, etc.) y, a continuación, use asistentes y clases para configurar la pertenencia.

El proceso básico se describe en la entrada de blog LA manera más básica de implementar seguridad ASP.NET (Razor). La mayoría del trabajo se realiza mediante los siguientes métodos y propiedades del asistente WebSecurity:

Para administrar roles puede usar las clases Roles y Pertenencia, como se describe en la entrada de blog.

Recursos adicionales