Compartir a través de


Información general sobre la autenticación de formularios (C#)

de Scott Mitchell

Nota:

Desde que se escribió este artículo, los proveedores de ASP.NET Pertenencia se han reemplazado por ASP.NET Identity. Se recomienda encarecidamente actualizar las aplicaciones para usar la plataforma ASP.NET Identity en lugar de los proveedores de pertenencia destacados en el momento en que se escribió este artículo. ASP.NET Identity tiene una serie de ventajas sobre el sistema de pertenencia ASP.NET, incluido :

  • Mejor rendimiento
  • Extensibilidad y capacidad de prueba mejoradas
  • Compatibilidad con OAuth, OpenID Connect y autenticación en dos fases
  • Compatibilidad con identidades basadas en declaraciones
  • Mejor interoperabilidad con ASP.Net Core

Descargar código o descargar PDF

En este tutorial, pasaremos de mera discusión a implementación; en concreto, veremos la implementación de la autenticación de formularios. La aplicación web que empezamos a construir en este tutorial se seguirá basando en tutoriales posteriores, ya que pasamos de la autenticación de formularios simples a la pertenencia y los roles.

Consulte este vídeo para obtener más información sobre este tema: Uso de la autenticación básica de formularios en ASP.NET.

Introducción

En el tutorial anterior se describen las distintas opciones de autenticación, autorización y cuenta de usuario proporcionadas por ASP.NET. En este tutorial, pasaremos de mera discusión a implementación; en concreto, veremos la implementación de la autenticación de formularios. La aplicación web que empezamos a construir en este tutorial se seguirá basando en tutoriales posteriores, ya que pasamos de la autenticación de formularios simples a la pertenencia y los roles.

Este tutorial comienza con una visión detallada del flujo de trabajo de autenticación de formularios, un tema que hemos tocado en el tutorial anterior. Después, crearemos un sitio web de ASP.NET a través del cual se describen los conceptos de autenticación de formularios. A continuación, configuraremos el sitio para que use la autenticación de formularios, crear una página de inicio de sesión simple y ver cómo determinar, en código, si un usuario está autenticado y, si es así, el nombre de usuario con el que inició sesión.

Comprender el flujo de trabajo de autenticación de formularios, habilitarlo en una aplicación web y crear las páginas de inicio de sesión y de inicio de sesión son todos los pasos fundamentales para crear una aplicación de ASP.NET que admita cuentas de usuario y autentique a los usuarios a través de una página web. Debido a esto, y como estos tutoriales se basan entre sí, le animaría a trabajar a través de este tutorial en su totalidad antes de pasar al siguiente, incluso si ya ha tenido experiencia en la configuración de la autenticación de formularios en proyectos anteriores.

Descripción del flujo de trabajo de autenticación de formularios

Cuando el entorno de ejecución de ASP.NET procesa una solicitud de un recurso de ASP.NET, como una página de ASP.NET o ASP.NET servicio web, la solicitud genera una serie de eventos durante su ciclo de vida. Hay eventos que se generan al principio y al final de la solicitud, los que se generan cuando la solicitud se autentica y autoriza, un evento generado en el caso de una excepción no controlada, etc. Para ver una lista completa de los eventos, consulte los eventos del objeto HttpApplication.

Los módulos HTTP son clases administradas cuyo código se ejecuta en respuesta a un evento determinado en el ciclo de vida de la solicitud. ASP.NET incluye una serie de módulos HTTP que realizan tareas esenciales en segundo plano. Dos módulos HTTP integrados que son especialmente relevantes para nuestra discusión son:

  • FormsAuthenticationModule : autentica al usuario inspeccionando el vale de autenticación de formularios, que normalmente se incluye en la recopilación de cookies del usuario. Si no hay ningún vale de autenticación de formularios presente, el usuario es anónimo.
  • UrlAuthorizationModule : determina si el usuario actual está autorizado para acceder a la dirección URL solicitada. Este módulo determina la autoridad consultando las reglas de autorización especificadas en los archivos de configuración de la aplicación. ASP.NET también incluye el FileAuthorizationModule que determina la autorización consultando las ACLs de los archivos solicitados.

Intenta autenticar al usuario antes de que FormsAuthenticationModule (y UrlAuthorizationModule) se ejecuten, mediante FileAuthorizationModule. Si el usuario que realiza la solicitud no está autorizado para acceder al recurso solicitado, el módulo de autorización finaliza la solicitud y devuelve un estado HTTP 401 No autorizado . En escenarios de autenticación de Windows, el estado HTTP 401 se devuelve al explorador. Este código de estado hace que el explorador solicite al usuario sus credenciales a través de un cuadro de diálogo modal. Sin embargo, con la autenticación de formularios, el estado HTTP 401 No autorizado nunca se envía al explorador porque FormsAuthenticationModule detecta este estado y lo modifica para redirigir al usuario a la página de inicio de sesión en su lugar (a través de un estado de redirección HTTP 302 ).

La responsabilidad de la página de inicio de sesión es determinar si las credenciales del usuario son válidas y, si es así, crear un vale de autenticación de formularios y redirigir al usuario a la página que intentaba visitar. El ticket de autenticación se incluye en las solicitudes siguientes a las páginas del sitio web, que FormsAuthenticationModule utiliza para identificar al usuario.

Flujo de trabajo de autenticación de formularios

Figura 1: Flujo de trabajo de autenticación de formularios

Recordar el vale de autenticación en las visitas a la página

Después de iniciar sesión, el vale de autenticación de formularios debe devolverse al servidor web en cada solicitud para que el usuario permanezca conectado mientras navega por el sitio. Normalmente, esto se logra colocando el vale de autenticación en la recopilación de cookies del usuario. Las cookies son archivos de texto pequeños que residen en el equipo del usuario y se transmiten en los encabezados HTTP en cada solicitud al sitio web que creó la cookie. Por lo tanto, una vez creado y almacenado el vale de autenticación de formularios en las cookies del navegador, cada visita posterior a ese sitio envía el vale de autenticación junto con la solicitud, identificando así al usuario.

Un aspecto de las cookies es su expiración, que es la fecha y hora en que el navegador descarta la cookie. Cuando expira la cookie de autenticación de formularios, el usuario ya no se puede autenticar y, por tanto, convertirse en anónimo. Cuando un usuario visita desde un terminal público, es probable que desee que su vale de autenticación expire cuando cierre su explorador. Sin embargo, al visitar desde casa, es posible que ese mismo usuario quiera que se recuerde el vale de autenticación en los reinicios del explorador para que no tengan que volver a iniciar sesión cada vez que visiten el sitio. A menudo, el usuario toma esta decisión en forma de una casilla "Recordarme" en la página de inicio de sesión. En el paso 3 examinaremos cómo implementar una casilla "Recordarme" en la página de inicio de sesión. En el tutorial siguiente se aborda la configuración de tiempo de espera del vale de autenticación en detalle.

Nota:

Es posible que el agente de usuario utilizado para iniciar sesión en el sitio web no admita cookies. En tal caso, ASP.NET puede usar vales de autenticación de formularios sin cookies. En este modo, el vale de autenticación se codifica en la dirección URL. Veremos cuándo se usan los vales de autenticación sin cookies y cómo se crean y administran en el siguiente tutorial.

Ámbito de autenticación de formularios

FormsAuthenticationModule es código administrado que forma parte del entorno de ejecución de ASP.NET. Antes de la versión 7 del servidor web de Internet Information Services (IIS) de Microsoft, había una barrera distinta entre la canalización HTTP de IIS y la canalización del entorno de ejecución de ASP.NET. En resumen, en IIS 6 y versiones anteriores, el FormsAuthenticationModule solo se ejecuta cuando se delega una solicitud de IIS al tiempo de ejecución de ASP.NET. De forma predeterminada, IIS procesa contenido estático , como páginas HTML y archivos css e imagen, y solo entrega las solicitudes al entorno de ejecución de ASP.NET cuando se solicita una página con una extensión de .aspx, .asmx o .ashx.

Sin embargo, IIS 7 permite canalizaciones integradas de IIS y ASP.NET. Con algunas opciones de configuración, puede configurar IIS 7 para invocar FormsAuthenticationModule para todas las solicitudes. Además, con IIS 7 puede definir reglas de autorización de direcciones URL para archivos de cualquier tipo. Para obtener más información, vea Cambios entre la seguridad de IIS6 e IIS7, la seguridad de la plataforma web y descripción de la autorización de direcciones URL de IIS7.

En resumen, en versiones anteriores a IIS 7, solo puedes usar autenticación de formularios para proteger los recursos manejados por el tiempo de ejecución de ASP.NET. Del mismo modo, las reglas de autorización de direcciones URL solo se aplican a los recursos administrados por el entorno de ejecución de ASP.NET. Pero con IIS 7 es posible integrar FormsAuthenticationModule y UrlAuthorizationModule en la canalización HTTP de IIS, lo que amplía esta funcionalidad a todas las solicitudes.

Paso 1: Crear un sitio web de ASP.NET para esta serie de tutoriales

Para llegar al público lo más amplio posible, el sitio web de ASP.NET que crearemos en esta serie se hará con la versión gratuita de Visual Web Developer 2008. Implementaremos la base de datos de SqlMembershipProvider usuarios en un Microsoft SQL Server 2005 Express Edition. Si usa Visual Studio 2005 o una edición diferente de Visual Studio 2008 o SQL Server, no se preocupe: los pasos serán casi idénticos y se señalarán las diferencias no triviales.

Nota:

La aplicación web de demostración que se usa en cada tutorial está disponible como descarga. Esta aplicación descargable se creó con Visual Web Developer 2008 destinado a la versión 3.5 de .NET Framework. Dado que la aplicación está destinada a .NET 3.5, su archivo de Web.config incluye elementos de configuración adicionales específicos de 3.5. En resumen, si aún no ha instalado .NET 3.5 en su computadora, entonces la aplicación web descargable no funcionará sin primero quitar el marcado específico de 3.5 de Web.config.

Para poder configurar la autenticación de formularios, primero necesitamos un sitio web ASP.NET. Empiece por crear un nuevo sitio web de ASP.NET basado en el sistema de archivos. Para ello, inicie Visual Web Developer y, a continuación, vaya al menú Archivo y elija Nuevo sitio web, mostrando el cuadro de diálogo Nuevo sitio web. Elija la plantilla sitio web de ASP.NET, establezca la lista desplegable Ubicación en Sistema de archivos, elija una carpeta para colocar el sitio web y establezca el idioma en C#. Esto creará un nuevo sitio web con una página de Default.aspx ASP.NET, una carpeta App_Data y un archivo Web.config.

Nota:

Visual Studio admite dos modos de administración de proyectos: proyectos de sitio web y proyectos de aplicaciones web. Los proyectos de sitio web carecen de un archivo de proyecto, mientras que los proyectos de aplicación web imitan la arquitectura del proyecto en Visual Studio .NET 2002/2003: incluyen un archivo de proyecto y compilan el código fuente del proyecto en un único ensamblado, que se coloca en la carpeta /bin. Visual Studio 2005 solo admitía inicialmente proyectos de sitio web, aunque el modelo de proyecto de aplicación web se volvió a introducir con Service Pack 1; Visual Studio 2008 ofrece ambos modelos de proyecto. Sin embargo, las ediciones Visual Web Developer 2005 y 2008 solo admiten proyectos de sitio web. Usaré el modelo de proyecto de sitio web. Si usa una edición que no es express y quiere usar el modelo de proyecto de aplicación web en su lugar, no dude en hacerlo, pero tenga en cuenta que puede haber algunas discrepancias entre lo que ve en la pantalla y los pasos que debe realizar frente a las capturas de pantalla que se muestran e instrucciones proporcionadas en estos tutoriales.

Crear un nuevo archivo en el sitio web System-Based

Figura 2: Crear un nuevo archivo en el sitio web System-Based (Haga clic para ver la imagen en tamaño completo)

Agregar una página maestra

A continuación, agregue una nueva página maestra al sitio en el directorio raíz denominado Site.master. Las páginas maestras permiten a un desarrollador de páginas definir una plantilla de todo el sitio que se puede aplicar a ASP.NET páginas. La principal ventaja de las páginas maestras es que la apariencia general del sitio se puede definir en una sola ubicación, lo que facilita la actualización o ajuste del diseño del sitio.

Agregar una página maestra denominada Site.master al sitio web

Figura 3: Agregar una página maestra denominada Site.master al sitio web (haga clic para ver la imagen de tamaño completo)

Defina el diseño de página de todo el sitio aquí en la página maestra. Puede usar la vista de diseño y agregar cualquier diseño o controles web que necesite, o bien puede añadir el marcado manualmente en la vista Origen. He estructurado el diseño de mi página maestra para imitar el diseño usado en mi serie de tutoriales "Trabajar con Datos en ASP.NET 2.0" (consulte la figura 4). La página maestra usa hojas de estilo en cascada para la colocación y los estilos con la configuración de CSS definida en el archivo Style.css (que se incluye en la descarga asociada a este tutorial). Aunque no se puede deducir del marcado que se muestra a continuación, las reglas CSS se definen de manera que el contenido del <div> de navegación esté posicionado absolutamente para que se muestre a la izquierda y tenga un ancho fijo de 200 píxeles.

<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Forms Authentication, Authorization, and User Accounts</title>
    <link href="Styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <div id="wrapper">
        <form id="form1" runat="server">
        
            <div id="header">
                <span class="title">User Account Tutorials</span>
            </div>
        
            <div id="content">
                <asp:contentplaceholder id="MainContent" runat="server">
                  <!-- Page-specific content will go here... -->
                </asp:contentplaceholder>
            </div>
            
            <div id="navigation">
                TODO: Menu will go here...
            </div>
        </form>
    </div>
</body>
</html>

Una página maestra define tanto el diseño de página estático como las regiones que pueden editar las páginas ASP.NET que usan la página maestra. Estas regiones editables de contenido se indican mediante el ContentPlaceHolder control, que se puede ver dentro del <div> de contenido. Nuestra página maestra tiene una sola ContentPlaceHolder (MainContent), pero las páginas maestras pueden tener varios ContentPlaceHolders.

Con el marcado especificado anteriormente, al cambiar a la vista Diseño se muestra el diseño de la página maestra. Cualesquiera páginas ASP.NET que usen esta página maestra tendrán este diseño uniforme, con la capacidad de especificar el etiquetado de la MainContent región.

Página maestra, cuando se ve a través de la vista Diseño

Figura 4: Página maestra, cuando se ve a través de la vista diseño (haga clic para ver la imagen de tamaño completo)

Crear páginas de contenido

En este punto tenemos una página Default.aspx en nuestro sitio web, pero no usa la página maestra que acabamos de crear. Aunque es posible manipular el marcado declarativo de una página web para usar una página maestra, si la página aún no contiene contenido, es más fácil eliminar la página y volver a agregarla al proyecto, especificando la página maestra que se va a usar. Por lo tanto, empiece eliminando Default.aspx del proyecto.

A continuación, haga clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones y elija agregar un nuevo formulario web denominado Default.aspx. Esta vez, active la casilla "Seleccionar página maestra" y elija la página maestra Site.master de la lista.

Agregar una nueva página Default.aspx eligiendo una página maestra

Figura 5: Agregar una nueva página de Default.aspx elegir seleccionar una página maestra (haga clic para ver la imagen de tamaño completo)

Utilice la Página Maestra Site.master

Figura 6: Usar la página maestra de Site.master

Nota:

Si usa el modelo de proyecto de aplicación web, el cuadro de diálogo Agregar nuevo elemento no incluye una casilla "Seleccionar página maestra". En su lugar, debe agregar un elemento de tipo "Formulario de contenido web". Después de elegir la opción "Formulario de contenido web" y presionar Agregar, Visual Studio mostrará el mismo cuadro de diálogo Seleccionar una página principal que se muestra en la Figura 6.

El nuevo marcado declarativo de la página Default.aspx incluye solo una directiva @Page que especifica la ruta al archivo de la página maestra, y un control Content para el ContentPlaceHolder MainContent de la página maestra.

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
</asp:Content>

Por ahora, deje Default.aspx vacío. Volveremos a él más adelante en este tutorial para agregar contenido.

Nota:

Nuestra página maestra incluye una sección para un menú o alguna otra interfaz de navegación. Crearemos una interfaz de este tipo en un tutorial futuro.

Paso 2: Habilitación de la autenticación de formularios

Con el sitio web de ASP.NET creado, nuestra siguiente tarea es habilitar la autenticación de formularios. La configuración de autenticación de la aplicación se especifica a través del <authentication> elemento de Web.config. El <authentication> elemento contiene un solo atributo denominado mode que especifica el modelo de autenticación utilizado por la aplicación. Este atributo puede tener uno de los cuatro valores siguientes:

  • Windows : como se describe en el tutorial anterior, cuando una aplicación usa la autenticación de Windows, es responsabilidad del servidor web autenticar al visitante, y esto suele hacerse a través de la autenticación básica, implícita o integrada de Windows.
  • Formularios: los usuarios se autentican a través de un formulario en una página web.
  • Passport: los usuarios se autentican mediante la red passport de Microsoft.
  • Ninguno: no se usa ningún modelo de autenticación; todos los visitantes son anónimos.

De forma predeterminada, ASP.NET aplicaciones usan la autenticación de Windows. Para cambiar el tipo de autenticación a la autenticación de formularios, es necesario modificar el <authentication> atributo de modo del elemento en Forms.

Si el proyecto aún no contiene un archivo Web.config, agregue uno ahora haciendo clic con el botón derecho en el nombre del proyecto en el Explorador de soluciones, seleccionando Agregar nuevo elemento y, a continuación, agregando un archivo de configuración web.

Si el proyecto aún no incluye Web.config, agréguelo ahora.

Figura 7: Si el proyecto aún no incluye Web.config, agréguelo ahora (haga clic para ver la imagen de tamaño completo)

A continuación, busque el <authentication> elemento y actualícelo para usar la autenticación de formularios. Después de este cambio, el marcado del archivo Web.config debe tener un aspecto similar al siguiente:

<configuration>
    <system.web>
        ... Unrelated configuration settings and comments removed for brevity ...
        <!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
        <authentication mode="Forms" />
    </system.web>
</configuration>

Nota:

Dado que Web.config es un archivo XML, es crucial respetar las mayúsculas. Asegúrese de establecer el atributo mode en Forms, con una mayúscula "F". Si usa un uso diferente de mayúsculas y minúsculas, como "formularios", recibirá un error de configuración al visitar el sitio en un navegador.

El <authentication> elemento puede incluir opcionalmente un <forms> elemento secundario que contenga la configuración específica de la autenticación de formularios. Por ahora, vamos a usar la configuración de autenticación de formularios predeterminada. Exploraremos el <forms> elemento secundario con más detalle en el siguiente tutorial.

Paso 3: Crear la página de inicio de sesión

Para admitir la autenticación de formularios, nuestro sitio web necesita una página de inicio de sesión. Como se describe en la sección "Descripción del flujo de trabajo de autenticación de formularios", el FormsAuthenticationModule redirigirá automáticamente al usuario a la página de inicio de sesión si intenta acceder a una página que no está autorizada para ver. También hay ASP.NET controles web que mostrarán un vínculo a la página de inicio de sesión a usuarios anónimos. Esto plantea la pregunta "¿ Cuál es la dirección URL de la página de inicio de sesión?"

De forma predeterminada, el sistema de autenticación de formularios espera que la página de inicio de sesión se llame Login.aspx y se coloque en el directorio raíz de la aplicación web. Si desea usar una dirección URL de página de inicio de sesión diferente, puede hacerlo especificando en Web.config. Veremos cómo hacerlo en el tutorial posterior.

La página de inicio de sesión tiene tres responsabilidades:

  1. Proporcione una interfaz que permita al visitante escribir sus credenciales.
  2. Determine si las credenciales enviadas son válidas.
  3. Para iniciar sesión, el usuario crea el vale de autenticación de formularios.

Crear la interfaz de usuario de la página de inicio de sesión

Comencemos con la primera tarea. Agregue una nueva página de ASP.NET al directorio raíz del sitio denominado Login.aspx y asóciela a la página maestra Site.master.

Agregar una nueva página de ASP.NET denominada Login.aspx

Figura 8: Agregar una nueva página de ASP.NET denominada Login.aspx (haga clic para ver la imagen de tamaño completo)

La interfaz típica de la página de inicio de sesión consta de dos cuadros de texto ( uno para el nombre del usuario, otro para su contraseña) y un botón para enviar el formulario. Los sitios web suelen incluir una casilla "Recordarme" que, si está activada, conserva el vale de autenticación resultante en los reinicios del explorador.

Agregue dos cuadros de texto a Login.aspx y establezca sus ID propiedades en UserName y Password, respectivamente. Cambia también la propiedad TextMode a Password. A continuación, agregue un control CheckBox y establezca su ID propiedad en RememberMe y su Text propiedad en "Recordarme". Después, agregue un botón denominado LoginButton cuya Text propiedad esté establecida en "Login". Y, por último, agregue un control Web Label y establezca su ID propiedad en InvalidCredentialsMessage, su Text propiedad en "Su nombre de usuario o contraseña no es válido. Inténtelo de nuevo.", su propiedad ForeColor a Rojo y su propiedad Visible a False.

En este punto, la pantalla debe ser similar a la captura de pantalla de la figura 9 y la sintaxis declarativa de la página debe ser similar a la siguiente:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Login.aspx.cs" Inherits="Login" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
    <h1>
        Login</h1>
    <p>
        Username:
        <asp:TextBox ID="UserName" runat="server"></asp:TextBox></p>
    <p>
        Password:
        <asp:TextBox ID="Password" runat="server" TextMode="Password"></asp:TextBox></p>
    <p>
        <asp:CheckBox ID="RememberMe" runat="server" Text="Remember Me" /> </p>
    <p>
        <asp:Button ID="LoginButton" runat="server" Text="Login" OnClick="LoginButton_Click" /> </p>
    <p>
        <asp:Label ID="InvalidCredentialsMessage" runat="server" ForeColor="Red" Text="Your username or password is invalid. Please try again."
            Visible="False"></asp:Label> </p>
</asp:Content>

La página De inicio de sesión contiene dos cuadros de texto, una casilla, un botón y una etiqueta

Figura 9: La página de inicio de sesión contiene dos cuadros de texto, una casilla, un botón y una etiqueta (haga clic para ver la imagen de tamaño completo)

Por último, cree un controlador de eventos para el evento Click de LoginButton. En el Diseñador, simplemente haga doble clic en el control Botón para crear este controlador de eventos.

Determinar si las credenciales proporcionadas son válidas

Ahora es necesario implementar la tarea 2 en el controlador de eventos Click del botón, lo que determina si las credenciales proporcionadas son válidas. Para ello, debe haber un almacén de usuarios que contenga todas las credenciales de los usuarios para poder determinar si las credenciales proporcionadas coinciden con las credenciales conocidas.

Antes de ASP.NET 2.0, los desarrolladores eran responsables de implementar sus propios almacenes de usuario y escribir el código para validar las credenciales proporcionadas en el almacén. La mayoría de los desarrolladores implementarían el almacén de usuarios en una base de datos, creando una tabla denominada Usuarios con columnas como UserName, Password, Email, LastLoginDate, etc. Esta tabla, a continuación, tendría un registro por cuenta de usuario. La comprobación de las credenciales proporcionadas por un usuario implicaría consultar la base de datos para un nombre de usuario coincidente y, a continuación, asegurarse de que la contraseña de la base de datos se corresponde con la contraseña proporcionada.

Con ASP.NET 2.0, los desarrolladores deben usar uno de los proveedores de pertenencia para administrar el almacén de usuarios. En esta serie de tutoriales usaremos SqlMembershipProvider, que usa una base de datos de SQL Server para el almacén de usuarios. Al usar SqlMembershipProvider, es necesario implementar un esquema de base de datos específico que incluya las tablas, vistas y procedimientos almacenados esperados por el proveedor. Examinaremos cómo implementar este esquema en el tutorial Creación del esquema de pertenencia en SQL Server . Con el proveedor de pertenencia implementado, validar las credenciales del usuario es tan sencillo como llamar al método ValidateUser(username, password) de la clase Membership, que devuelve un valor booleano que indica si la validez de la combinación de nombre de usuario y contraseña. Al ver que aún no hemos implementado el almacén de usuarios de SqlMembershipProvider, no podemos usar el método ValidateUser de la clase Membership en este momento.

En lugar de tardar el tiempo en crear nuestra propia tabla de base de datos Usuarios personalizados (que sería obsoleta una vez implementada SqlMembershipProvider), vamos a codificar de forma rígida las credenciales válidas dentro de la propia página de inicio de sesión. En el controlador de eventos Click de LoginButton, agregue el código siguiente:

protected void LoginButton_Click(object sender, EventArgs e)
{
    // Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
    string[] users = { "Scott", "Jisun", "Sam" };
    string[] passwords = { "password", "password", "password" };
    for (int i = 0; i < users.Length; i++)
    {
        bool validUsername = (string.Compare(UserName.Text, users[i], true) == 0);
        bool validPassword = (string.Compare(Password.Text, passwords[i], false) == 0);
        if (validUsername && validPassword)
        {
            // TODO: Log in the user...
            // TODO: Redirect them to the appropriate page
        }
    }
    // If we reach here, the user's credentials were invalid
    InvalidCredentialsMessage.Visible = true;
}

Como puede ver, hay tres cuentas de usuario válidas (Scott, Jisun y Sam) y las tres tienen la misma contraseña ("contraseña"). El código recorre en bucle las matrices de usuarios y contraseñas que buscan una coincidencia válida de nombre de usuario y contraseña. Si el nombre de usuario y la contraseña son válidos, es necesario iniciar sesión del usuario y, a continuación, redirigirlos a la página adecuada. Si las credenciales no son válidas, se muestra la etiqueta InvalidCredentialsMessage.

Cuando un usuario escribe credenciales válidas, mencioné que luego se le redirigirá a la "página adecuada". ¿Cuál es la página adecuada, sin embargo? Recuerde que cuando un usuario visita una página que no está autorizada para ver, FormsAuthenticationModule los redirige automáticamente a la página de inicio de sesión. Al hacerlo, incluye la dirección URL solicitada en la cadena de consulta a través del parámetro ReturnUrl. Es decir, si un usuario intentó visitar ProtectedPage.aspx y no estaba autorizado para hacerlo, FormsAuthenticationModule los redirigiría a:

Login.aspx? ReturnUrl=ProtectedPage.aspx

Después de iniciar sesión correctamente, el usuario debe redirigirse de nuevo a ProtectedPage.aspx. Como alternativa, los usuarios pueden visitar la página de inicio de sesión en su propia volición. En ese caso, después de iniciar sesión con el usuario, este debe ser enviado a la página Default.aspx de la carpeta raíz.

Iniciar sesión en el usuario

Suponiendo que las credenciales proporcionadas son válidas, es necesario crear un boleto de autenticación de formularios, lo que permite iniciar sesión del usuario en el sitio. La clase FormsAuthentication del espacio de nombres System.Web.Security proporciona métodos ordenados para iniciar sesión y cerrar sesión de usuarios a través del sistema de autenticación de formularios. Aunque hay varios métodos en la clase FormsAuthentication, los tres que nos interesan en este momento son:

  • GetAuthCookie(username, persistCookie): crea un vale de autenticación de formularios para el nombre de usuario proporcionado. A continuación, este método crea y devuelve un objeto HttpCookie que contiene el contenido del vale de autenticación. Si persistCookie es true, se crea una cookie persistente.
  • SetAuthCookie(username, persistCookie): llama al método GetAuthCookie(username, persistCookie) para generar la cookie de autenticación de formularios. Luego, este método añade la cookie devuelta por GetAuthCookie a la colección de Cookies (suponiendo que se utiliza autenticación de formularios basada en cookies; de lo contrario, este método llama a una clase interna que maneja la lógica de tickets sin cookies).
  • RedirectFromLoginPage(username, persistCookie): este método llama a SetAuthCookie(username, persistCookie) y, a continuación, redirige al usuario a la página adecuada.

GetAuthCookie es útil cuando necesita modificar el ticket de autenticación antes de escribir la cookie en la colección Cookies. SetAuthCookie es útil si desea crear el vale de autenticación de formularios y agregarlo a la colección de cookies, pero no desea redirigir al usuario a la página correspondiente. Quizás quiera mantenerlos en la página de inicio de sesión o enviarlos a alguna página alternativa.

Puesto que queremos iniciar sesión como usuario y redirigirlo a la página adecuada, vamos a usar RedirectFromLoginPage. Actualice el controlador de eventos Click de LoginButton, reemplazando las dos líneas TODO comentadas por la siguiente línea de código:

FormsAuthentication.RedirectFromLoginPage(UserName.Text, RememberMe.Checked);

Al crear el ticket de autenticación de formularios, utilizamos la propiedad Text del cuadro de texto UserName para el parámetro nombre de usuario del ticket de autenticación de formularios, y el estado activado de la casilla RememberMe CheckBox para el parámetro persistCookie.

Para probar la página de inicio de sesión, visite en un explorador. Para empezar, escriba credenciales no válidas, como un nombre de usuario de "Nope" y una contraseña de "incorrecto". Al hacer clic en el botón Iniciar sesión, se producirá una actualización de página y se mostrará el mensaje InvalidCredentialsMessage.

La etiqueta InvalidCredentialsMessage se muestra al escribir credenciales no válidas.

Figura 10: La etiqueta InvalidCredentialsMessage se muestra al escribir credenciales no válidas (haga clic para ver la imagen de tamaño completo).

A continuación, escriba credenciales válidas y haga clic en el botón Inicio de sesión. Esta vez, cuando se produce el postback, se crea un ticket de autenticación de formularios y se le redirige automáticamente a Default.aspx. En este momento ha iniciado sesión en el sitio web, aunque no hay indicaciones visuales para indicar que ha iniciado sesión actualmente. En el paso 4 veremos cómo determinar mediante programación si un usuario ha iniciado sesión o no, así como cómo identificar al usuario que visita la página.

Paso 5 examina las técnicas para registrar a un usuario fuera del sitio web.

Protección de la página de inicio de sesión

Cuando el usuario escribe sus credenciales y envía el formulario de página de inicio de sesión, las credenciales (incluida su contraseña) se transmiten a través de Internet al servidor web en texto sin formato. Esto significa que cualquier hacker que examine el tráfico de red puede ver el nombre de usuario y la contraseña. Para evitar esto, es esencial cifrar el tráfico de red mediante capas de sockets seguros (SSL). Esto garantizará que las credenciales (así como el marcado HTML de toda la página) se cifren desde el momento en que abandonan el explorador hasta que el servidor web los reciba.

A menos que su sitio web contenga información sensible, solo necesitará usar SSL en la página de inicio de sesión y en otras páginas donde la contraseña del usuario se enviaría a través de la red en texto sin formato. No es necesario preocuparse por proteger el vale de autenticación de formularios, ya que, de forma predeterminada, está cifrado y firmado digitalmente (para evitar alteraciones). En el siguiente tutorial se presenta un análisis más detallado sobre la seguridad de los tickets de autenticación de formularios.

Nota:

Muchos sitios web financieros y médicos están configurados para usar SSL en todas las páginas accesibles para los usuarios autenticados. Si va a crear este sitio web, puede configurar el sistema de autenticación de formularios para que el vale de autenticación de formularios solo se transmita a través de una conexión segura.

Paso 4: Detección de visitantes autenticados y determinación de su identidad

En este momento, hemos habilitado la autenticación de formularios y hemos creado una página de inicio de sesión rudimentaria, pero todavía tenemos que examinar cómo podemos determinar si un usuario está autenticado o anónimo. En determinados escenarios, es posible que deseemos mostrar datos o información diferentes en función de si un usuario autenticado o anónimo está visitando la página. Además, a menudo es necesario conocer la identidad del usuario autenticado.

Vamos a aumentar la página de Default.aspx existente para ilustrar estas técnicas. En Default.aspx agregar dos controles Panel, uno denominado AuthenticatedMessagePanel y otro denominado AnonymousMessagePanel. Agregue un control Label denominado WelcomeBackMessage en el primer Panel. En el segundo Panel, agregue un control HyperLink, establezca su propiedad Text en "Iniciar sesión" y su propiedad NavigateUrl en "~/Login.aspx". En este momento, el marcado declarativo para Default.aspx debe tener un aspecto similar al siguiente:

<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" Title="Untitled Page" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server">
    <asp:Panel runat="server" ID="AuthenticatedMessagePanel">
        <asp:Label runat="server" ID="WelcomeBackMessage"></asp:Label>
    </asp:Panel>
    
    <asp:Panel runat="Server" ID="AnonymousMessagePanel">
        <asp:HyperLink runat="server" ID="lnkLogin" Text="Log In" NavigateUrl="~/Login.aspx"></asp:HyperLink>
    </asp:Panel>
</asp:Content>

Como probablemente haya adivinado por ahora, la idea aquí es mostrar solo el AuthenticatedMessagePanel para los visitantes autenticados y solo el AnonymousMessagePanel a los visitantes anónimos. Para ello, es necesario establecer estas propiedades Visibles de paneles en función de si el usuario ha iniciado sesión o no.

La propiedad Request.IsAuthenticated devuelve un valor booleano que indica si la solicitud se ha autenticado. Escriba el código siguiente en el código del controlador de eventos Page_Load:

protected void Page_Load(object sender, EventArgs e)
{
    if (Request.IsAuthenticated)
    {
        WelcomeBackMessage.Text = "Welcome back!";
    
        AuthenticatedMessagePanel.Visible = true;
        AnonymousMessagePanel.Visible = false;
    }
    else
    {
        AuthenticatedMessagePanel.Visible = false;
        AnonymousMessagePanel.Visible = true;
    }
}

Con este código en su lugar, visite Default.aspx a través de un explorador. Suponiendo que todavía tiene que iniciar sesión, verá un vínculo a la página de inicio de sesión (consulte la figura 11). Haga clic en este vínculo e inicie sesión en el sitio. Como vimos en el paso 3, después de escribir sus credenciales, se le devolverá a Default.aspx, pero esta vez la página muestra el mensaje "Bienvenido atrás!" (vea la figura 12).

Al visitar de forma anónima, se muestra un vínculo de inicio de sesión.

Figura 11: Al visitar de forma anónima, se muestra un vínculo de inicio de sesión

Se muestran los usuarios autenticados.

Figura 12: A los usuarios autenticados se les muestra el mensaje "¡Bienvenido de nuevo!"

Podemos determinar la identidad del usuario que ha iniciado sesión actualmente a través de la propiedad User del objeto HttpContext. El objeto HttpContext representa información sobre la solicitud actual y es el hogar de objetos comunes ASP.NET como Response, Request y Session, entre otros. La propiedad User representa el contexto de seguridad de la solicitud HTTP actual e implementa la interfaz IPrincipal.

La propiedad User se establece mediante FormsAuthenticationModule. En concreto, cuando FormsAuthenticationModule encuentra un vale de autenticación de formularios en la solicitud entrante, crea un nuevo objeto GenericPrincipal y lo asigna a la propiedad User.

Los objetos Principal (como GenericPrincipal) proporcionan información sobre la identidad del usuario y los roles a los que pertenecen. La interfaz IPrincipal define dos miembros:

Podemos determinar el nombre del visitante actual mediante el código siguiente:

cadena currentUsersName = User.Identity.Name;

Al usar la autenticación de formularios, se crea un objeto FormsIdentity para la propiedad Identity de GenericPrincipal. La clase FormsIdentity siempre devuelve la cadena "Forms" para su propiedad AuthenticationType y true para su propiedad IsAuthenticated. La propiedad Name devuelve el nombre de usuario especificado al crear el vale de autenticación de formularios. Además de estas tres propiedades, FormsIdentity incluye acceso al vale de autenticación subyacente a través de su propiedad Ticket. La propiedad Ticket devuelve un objeto de tipo FormsAuthenticationTicket, que tiene propiedades como Expiration, IsPersistent, IssueDate, Name, etc.

El punto importante que hay que quitar aquí es que el parámetro username especificado en los métodos FormsAuthentication.GetAuthCookie(username, persistCookie), FormsAuthentication.SetAuthCookie(username, persistCookie) y FormsAuthentication.RedirectFromLoginPage(username, persistCookie) es el mismo valor devuelto por User.Identity.Name. Además, el vale de autenticación creado por estos métodos está disponible mediante la conversión de User.Identity a un objeto FormsIdentity y, a continuación, el acceso a la propiedad Ticket:

FormsIdentity ident = User.Identity as FormsIdentity;
FormsAuthenticationTicket authTicket = ident.Ticket;

Vamos a proporcionar un mensaje más personalizado en Default.aspx. Actualice el controlador de eventos Page_Load para que a la propiedad Text de la etiqueta WelcomeBackMessage se le asigne la cadena "Welcome back, username!"

WelcomeBackMessage.Text = "Bienvenido de nuevo, " + User.Identity.Name + "!";

En la figura 13 se muestra el efecto de esta modificación (al iniciar sesión como usuario Scott).

El mensaje de bienvenida incluye el nombre del usuario que ha iniciado sesión actualmente.

Figura 13: El mensaje de bienvenida incluye el nombre del usuario que ha iniciado sesión actualmente

Uso de los controles LoginView e LoginName

Mostrar contenido diferente para usuarios autenticados y anónimos es un requisito común; por lo tanto, se muestra el nombre del usuario que ha iniciado sesión actualmente. Por ese motivo, ASP.NET incluye dos controles web que proporcionan la misma funcionalidad que se muestra en la figura 13, pero sin necesidad de escribir una sola línea de código.

El control LoginView es un control web basado en plantillas que facilita la visualización de datos diferentes a usuarios autenticados y anónimos. LoginView incluye dos plantillas predefinidas:

  • AnonymousTemplate: cualquier marcado agregado a esta plantilla solo se muestra a los visitantes anónimos.
  • LoggedInTemplate – el código de esta plantilla solo se muestra a los usuarios autenticados.

Vamos a agregar el control LoginView a la página maestra de nuestro sitio, Site.master. En lugar de agregar solo el control LoginView, vamos a agregar un nuevo control ContentPlaceHolder y, a continuación, colocaremos el control LoginView dentro de ese nuevo ContentPlaceHolder. La justificación de esta decisión se hará evidente en breve.

Nota:

Además de AnonymousTemplate y LoggedInTemplate, el control LoginView puede incluir plantillas específicas del rol. Las plantillas específicas de rol muestran el marcado solo para los usuarios que pertenecen a un rol especificado. Examinaremos las características basadas en roles del control LoginView en un tutorial futuro.

Empiece agregando un ContentPlaceHolder denominado LoginContent a la página maestra dentro del elemento <div> de navegación. Simplemente puede arrastrar un control ContentPlaceHolder desde el Cuadro de herramientas a la vista Origen, colocando el código resultante justo encima del texto "TODO: Menu va a ir aquí...".

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

A continuación, agregue un control LoginView dentro de LoginContent ContentPlaceHolder. El contenido colocado en los controles ContentPlaceHolder de la página maestra se considera contenido predeterminado para ContentPlaceHolder. Es decir, ASP.NET páginas que usan esta página maestra pueden especificar su propio contenido para cada ContentPlaceHolder o usar el contenido predeterminado de la página maestra.

LoginView y otros controles relacionados con el inicio de sesión se encuentran en la pestaña Inicio de sesión del cuadro de herramientas.

Control LoginView en el cuadro de herramientas

Figura 14: Control LoginView en el cuadro de herramientas

A continuación, agregue dos < elementos br / > inmediatamente después del control LoginView, pero aún dentro del ContentPlaceHolder. En este punto, el código del elemento de navegación <div> debe tener un aspecto similar al siguiente:

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
        </asp:LoginView>
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Las plantillas de LoginView se pueden definir desde el Diseñador o el marcado declarativo. En el Diseñador de Visual Studio, expanda la etiqueta inteligente loginView, que enumera las plantillas configuradas en una lista desplegable. Escriba el texto "Hello, stranger" en AnonymousTemplate; A continuación, agregue un control HyperLink y establezca sus propiedades Text y NavigateUrl en "Iniciar sesión" y "~/Login.aspx", respectivamente.

Después de configurar AnonymousTemplate, cambie a LoggedInTemplate y escriba el texto "Welcome back, ". A continuación, arrastre un control LoginName desde el cuadro de herramientas a la instancia de LoggedInTemplate, colocándolo inmediatamente después del texto "Bienvenido atrás". El control LoginName, como su nombre indica, muestra el nombre del usuario que ha iniciado sesión actualmente. Internamente, el control LoginName simplemente genera la propiedad User.Identity.Name

Después de realizar estas adiciones a las plantillas de LoginView, el marcado debe ser similar al siguiente:

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
            <LoggedInTemplate>
                Welcome back,
                <asp:LoginName ID="LoginName1" runat="server" />.
            </LoggedInTemplate>
            <AnonymousTemplate>
                Hello, stranger.
                <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
            </AnonymousTemplate>
        </asp:LoginView>
        
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Con esta adición a la página maestra Site.master, cada página de nuestro sitio web mostrará un mensaje diferente en función de si el usuario está autenticado. En la figura 15 se muestra la página Default.aspx cuando el usuario Jisun visita a través de un explorador. El mensaje "Bienvenido atrás, Jisun" se repite dos veces: una vez en la sección de navegación de la página maestra de la izquierda (a través del control LoginView que acabamos de agregar) y una vez en el área de contenido del Default.aspx (a través de controles de Panel y lógica de programación).

Se muestra el control LoginView

Figura 15: El control LoginView muestra "Bienvenido atrás, Jisun".

Dado que agregamos loginView a la página maestra, puede aparecer en todas las páginas de nuestro sitio. Sin embargo, puede haber páginas web en las que no queremos mostrar este mensaje. Una de estas páginas es la página de inicio de sesión, ya que un vínculo a la página de inicio de sesión parece fuera de su lugar. Puesto que colocamos el control LoginView en un ContentPlaceHolder en la página maestra, podemos invalidar este marcado predeterminado en nuestra página de contenido. Abra Login.aspx y vaya al Diseñador. Dado que no hemos definido explícitamente un control de contenido en Login.aspx para el LoginContent ContentPlaceHolder de la página maestra, la página de inicio de sesión mostrará el marcado predeterminado de la página maestra para este ContentPlaceHolder. Puede verlo a través del Diseñador – el ContentPlaceHolder de LoginContent muestra el marcado predeterminado (el control LoginView).

La página Inicio de sesión muestra el contenido predeterminado de la página maestra LoginContent ContentPlaceHolder

Figura 16: La página Inicio de sesión muestra el contenido predeterminado para el loginContent ContentPlaceHolder de la página maestra (haga clic para ver la imagen de tamaño completo)

Para invalidar el marcado predeterminado para LoginContent ContentPlaceHolder, simplemente haga clic con el botón derecho en la región del Diseñador y elija la opción Crear contenido personalizado en el menú contextual. (Cuando se usa Visual Studio 2008, ContentPlaceHolder incluye una etiqueta inteligente que, cuando se selecciona, ofrece la misma opción). Esto agrega un nuevo control Content al marcado de la página y, por tanto, nos permite definir contenido personalizado para esta página. Puede agregar un mensaje personalizado aquí, como "Inicie sesión...", pero vamos a dejar esto en blanco.

Nota:

En Visual Studio 2005, la creación de contenido personalizado crea un control Content vacío en la página ASP.NET. Sin embargo, en Visual Studio 2008, la creación de contenido personalizado copia el contenido predeterminado de la página maestra en el control Contenido recién creado. Si usa Visual Studio 2008, después de crear el nuevo control Contenido, asegúrese de borrar el contenido copiado de la página maestra.

En la figura 17 se muestra la página Login.aspx cuando se visita desde un explorador después de realizar este cambio. Tenga en cuenta que no hay ningún mensaje "Hello, stranger" o "Welcome back, username" en el <div> de navegación izquierdo, como ocurre al visitar Default.aspx.

La página De inicio de sesión oculta el marcado predeterminado de LoginContent ContentPlaceHolder

Figura 17: La página de inicio de sesión oculta el marcado predeterminado LoginContent ContentPlaceHolder (haga clic para ver la imagen de tamaño completo)

Paso 5: Cerrar sesión

En el paso 3 hemos visto la creación de una página de inicio de sesión para registrar a un usuario en el sitio, pero todavía tenemos que ver cómo cerrar sesión de un usuario. Además de los métodos para registrar un usuario en, la clase FormsAuthentication también proporciona un método SignOut. El método SignOut simplemente destruye el ticket de autenticación de formularios, cerrando así la sesión del usuario en el sitio.

Ofrecer un vínculo de cierre de sesión es una característica tan común que ASP.NET incluye un control diseñado específicamente para cerrar la sesión de un usuario. El control LoginStatus muestra un LinkButton "Login" o "Logout" LinkButton, en función del estado de autenticación del usuario. Un "LinkButton" de Inicio de sesión se muestra para los usuarios anónimos, mientras que un "LinkButton" de Cierre de sesión se presenta a los usuarios autenticados. El texto de "Login" y "Logout" LinkButtons se puede configurar a través de las propiedades LoginText y LogoutText de LoginStatus.

Al hacer clic en el "Login" LinkButton se produce un postback, desde el que se realiza una redirección a la página de inicio de sesión. Al hacer clic en "Logout" LinkButton, el control LoginStatus invocará el método FormsAuthentication.SignOff y, a continuación, redirigirá al usuario a una página. La página a la que se redirige el usuario que ha cerrado sesión depende de la propiedad LogoutAction, que se puede asignar a uno de los tres valores siguientes:

  • Actualizar: valor predeterminado; redirige al usuario a la página que acaba de visitar. Si la página que acaba de visitar no permite a los usuarios anónimos, FormsAuthenticationModule redirigirá automáticamente al usuario a la página de inicio de sesión.

Es posible que tenga curiosidad por qué se realiza un redireccionamiento aquí. Si el usuario quiere permanecer en la misma página, ¿por qué necesita la redirección explícita? El motivo es porque, al hacer clic en el LinkButton "Logoff", el usuario todavía tiene el ticket de autenticación de formularios en su colección de cookies. Por lo tanto, la solicitud de postback es una solicitud autenticada. El control LoginStatus llama al método SignOut, pero esto sucede después de que FormsAuthenticationModule haya autenticado al usuario. Por lo tanto, una redirección explícita hace que el explorador vuelva a solicitar la página. Cuando el explorador vuelve a solicitar la página, se ha quitado el vale de autenticación de formularios y, por tanto, la solicitud entrante es anónima.

  • Redireccionamiento: el usuario se redirige a la dirección URL especificada por la propiedad LogoutPageUrl de LoginStatus.
  • RedirectToLoginPage: el usuario se redirige a la página de inicio de sesión.

Vamos a agregar un control LoginStatus a la página maestra y configurarlo para usar la opción Redirigir para enviar al usuario a una página que muestre un mensaje que confirme que se ha cerrado la sesión. Empiece por crear una página en el directorio raíz denominado Logout.aspx. No olvide asociar esta página a la página maestra Site.master. A continuación, ingrese un mensaje en el código fuente de la página indicando al usuario que ha cerrado sesión.

A continuación, vuelva a la página maestra Site.master y agregue un control LoginStatus debajo de LoginView en LoginContent ContentPlaceHolder. Establezca la propiedad LogoutAction del control LoginStatus en Redirect y su propiedad LogoutPageUrl en "~/Logout.aspx".

<div id="navigation">
    <asp:ContentPlaceHolder ID="LoginContent" runat="server">
        <asp:LoginView ID="LoginView1" runat="server">
            <LoggedInTemplate>
                Welcome back,
                <asp:LoginName ID="LoginName1" runat="server" />.
            </LoggedInTemplate>
            <AnonymousTemplate>
                Hello, stranger.
                <asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx">Log In</asp:HyperLink>
            </AnonymousTemplate>
        </asp:LoginView>
        <br />
        <asp:LoginStatus ID="LoginStatus1" runat="server" LogoutAction="Redirect" LogoutPageUrl="~/Logout.aspx" />
        
        <br /><br />
    </asp:ContentPlaceHolder>
   
    TODO: Menu will go here...
</div>

Dado que LoginStatus está fuera del control LoginView, aparecerá para ambos usuarios anónimos y autenticados, pero está bien porque LoginStatus mostrará correctamente un LinkButton «Login» o «Logout». Con la adición del control LoginStatus, el HyperLink "Iniciar sesión" en AnonymousTemplate es superfluo, así que quítelo.

En la figura 18 se muestra Default.aspx cuando Jisun realiza una visita. Tenga en cuenta que la columna izquierda muestra el mensaje "Bienvenido de nuevo, Jisun" junto con un vínculo para cerrar sesión. Al hacer clic en el vínculo de cierre de sesión, Jisun se desconecta del sistema y, a continuación, se le redirige a Logout.aspx. Como se muestra en la figura 19, en el momento en que Jisun alcanza Logout.aspx ya se ha cerrado la sesión y, por tanto, es anónima. Por lo tanto, la columna izquierda muestra el texto "Bienvenido, extraño" y un vínculo a la página de inicio de sesión.

default.aspx muestra

Figura 18: Default.aspx muestra "Bienvenido atrás, Jisun" junto con un linkButton de "Cierre de sesión" (haga clic para ver la imagen de tamaño completo)

Logout.aspx muestra

Figura 19: Logout.aspx muestra "Bienvenido, extraño" junto con un LinkButton de "Inicio de sesión" (haga clic para ver la imagen de tamaño completo)

Nota:

Te animamos a personalizar la página de Logout.aspx para ocultar el elemento LoginContent ContentPlaceHolder de la página maestra (como hicimos para Login.aspx en el paso 4). El motivo es porque el LinkButton "Login" renderizado por el control LoginStatus (el que se encuentra debajo de "Hello, stranger") envía al usuario a la página de inicio de sesión, pasando la URL actual como parámetro en el querystring ReturnUrl. En resumen, si un usuario que ha cerrado la sesión hace clic en el linkButton "Login" de LoginStatus y, a continuación, inicia sesión, se le redirigirá de nuevo a Logout.aspx, lo que podría confundir fácilmente al usuario.

Resumen

En este tutorial se ha iniciado un examen del flujo de trabajo de autenticación de formularios y, a continuación, se ha vuelto a implementar la autenticación de formularios en una aplicación de ASP.NET. La autenticación de formularios se basa en FormsAuthenticationModule, que tiene dos responsabilidades: identificar a los usuarios en función de su vale de autenticación de formularios y redirigir usuarios no autorizados a la página de inicio de sesión.

La clase FormsAuthentication de .NET Framework incluye métodos para crear, inspeccionar y quitar vales de autenticación de formularios. La propiedad Request.IsAuthenticated y el objeto User proporcionan compatibilidad mediante programación adicional para determinar si una solicitud está autenticada e información sobre la identidad del usuario. También hay los controles LoginView, LoginStatus y LoginName Web, que proporcionan a los desarrolladores una forma rápida y sin código para realizar muchas tareas comunes relacionadas con el inicio de sesión. Examinaremos estos y otros controles web relacionados con el inicio de sesión con mayor detalle en los tutoriales futuros.

En este tutorial se proporciona información general sobre la autenticación de formularios. No examinamos las opciones de configuración ordenadas, analizamos cómo funcionan los vales de autenticación de formularios sin cookies o exploramos cómo ASP.NET protege el contenido del vale de autenticación de formularios.

¡Feliz programación!

Lecturas adicionales

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

Aprendizaje en vídeo sobre temas incluidos en este tutorial

Acerca del autor

Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha estado trabajando con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 en 24 horas. Se le puede localizar en mitchell@4GuysFromRolla.com.

Gracias especial a...

Esta serie de tutoriales fue revisada por muchos revisores de gran ayuda. El revisor principal de este tutorial fue esta serie de tutoriales fue revisada por muchos revisores útiles. Los revisores principales de este tutorial incluyen Alicja Maziarz, John Suru y Teresa Murphy. ¿Le interesa revisar mis próximos artículos de MSDN? Si es así, envíame un mensaje a mitchell@4GuysFromRolla.com.