Información general sobre la autenticación de formularios (VB)

por Scott Mitchell

Nota:

Desde que se escribió este artículo, los proveedores de pertenencia a ASP.NET han sido reemplazados 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, incluidos:

  • Mejor rendimiento
  • Extensibilidad y capacidad de prueba mejoradas
  • Compatibilidad con OAuth, OpenID Connect y autenticación en dos fases
  • Compatibilidad con identidades basadas en notificaciones
  • 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á desarrollando en tutoriales posteriores a medida 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 de formularios básicos en ASP.NET.

Introducción

En el tutorial anterior se describieron 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á desarrollando en tutoriales posteriores a medida 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 y de cierre de sesión son todos 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 a que estos tutoriales se basan entre sí, le animaría a trabajar a seguir 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 o servicio web de ASP.NET, 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 hay 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 colecció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 FileAuthorizationModule que determina la autoridad consultando las ACL de los archivos solicitados.

FormsAuthenticationModule intenta autenticar al usuario antes de la ejecución de UrlAuthorizationModule (y 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 HTTP 302 Redirección).

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 vale de autenticación se incluye en las solicitudes posteriores a las páginas del sitio web, que usa FormsAuthenticationModule para identificar al usuario.

The Forms Authentication Workflow

Figura 01: Flujo de trabajo de autenticación de formularios (haga clic para ver la imagen a tamaño completo).

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 que 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.

Nota:

La aplicación web de demo 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 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 equipo, la aplicación web descargable no funcionará sin eliminar primero el marcado específico de 3.5 de Web.config.

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, se convierte 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 tenga que volver a iniciar sesión cada vez que visite el sitio. A menudo, el usuario toma esta decisión en forma de 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 del 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.

El á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, FormsAuthenticationModule solo se ejecuta cuando se delega una solicitud de IIS al entorno de ejecución de ASP.NET. De forma predeterminada, IIS procesa contenido estático, como páginas HTML y archivos CSS y de 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, consulte Cambios entre la seguridad de IIS6 e IIS7, 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 puede usar la autenticación de formularios para proteger los recursos administrados 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 a un público lo más amplio posible, el sitio web de ASP.NET que crearemos en esta serie se creará con la versión gratuita de Microsoft de Visual Studio 2008: Visual Web Developer 2008. Implementaremos el almacén de usuarios SqlMembershipProvider en una base de datos de 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 importantes.

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 VB. Esto creará un 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 y las instrucciones proporcionadas en estos tutoriales.

Create a New File System-Based Web Site

Figura 02: Crear un nuevo sitio web basado en el sistema de archivos (haga clic para ver la imagen a 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 para todo el sitio que se puede aplicar a páginas ASP.NET. 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 el ajuste del diseño del sitio.

Add a Master Page Named Site.master to the Website

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

Defina el diseño de página para todo el sitio aquí en la página maestra. Puede usar la vista Diseño y agregar cualquier diseño o controles web que necesite, o bien puede agregar manualmente el marcado 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 estilos CSS para el posicionamiento y los estilos con la configuración CSS definida en el archivo Style.css (que se incluye en la descarga asociada de este tutorial). Aunque no se puede observar en el marcado que se muestra a continuación, las reglas CSS se definen de modo que el contenido del <div> de navegación esté absolutamente posicionado para que aparezca a la izquierda y tenga un ancho fijo de 200 píxeles.

<%@ Master Language="VB" CodeFile="Site.master.vb" 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 en las que se usa la página maestra. Estas áreas modificables de contenido se indican mediante el control ContentPlaceHolder, que se puede ver dentro del <div> del contenido. Nuestra página maestra tiene un solo 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. Cualquier página ASP.NET que use esta página maestra tendrá este diseño uniforme, con la capacidad de especificar el marcado de la región MainContent.

The Master Page, When Viewed Through the Design View

Figura 04: La página maestra cuando se ve a través de la vista Diseño (haga clic para ver la imagen a 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 opte por 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.

Add a New Default.aspx Page Choosing to Select a Master Page

Figura 05: Agregar una nueva página Default.aspx seleccionando una página maestra (haga clic para ver la imagen a tamaño completo).

Use the Site.master Master Page

Figura 06: Usar la página maestra Site.master (haga clic para ver la imagen a tamaño completo).

Nota:

Si usa el modelo de proyecto de aplicación web, el cuadro de diálogo Agregar nuevo elemento no incluye la 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 de hacer clic en Agregar, Visual Studio mostrará el mismo cuadro de diálogo Seleccionar un patrón 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 de acceso al archivo de página maestra y un Control de contenido del MainContent ContentPlaceHolder de la página maestra.

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

Por ahora, deje Default.aspx vacía. 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 elemento <autenticación> de Web.config. El elemento <authentication> 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.
  • Forms: los usuarios se autentican a través de un formulario en una página web.
  • Passport: los usuarios se autentican mediante la red de Microsoft Passport.
  • None: no se usa ningún modelo de autenticación; todos los visitantes son anónimos.

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

Si el proyecto aún no contiene ningún 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.

If Your Project Does Not Yet Include Web.config, Add It Now

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

A continuación, busque el elemento <authentication> y actualícelo para usar la autenticación de formularios. Después de este cambio, el marcado del archivo Web.config debe ser 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 importante el uso de mayúsculas y minúsculas. Asegúrese de establecer el atributo mode en Forms, con una letra F mayúscula. Si utiliza otro uso de mayúsculas y minúsculas, como formularios, recibirá un error de configuración al visitar el sitio a través de un explorador.

El elemento <authentication> puede incluir opcionalmente un elemento secundario <forms> 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 elemento secundario <forms> 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, 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á autorizado para ver. También hay controles web de ASP.NET 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 otra dirección URL de página de inicio de sesión, puede hacerlo especificándolo en Web.config. Veremos cómo hacerlo en el tutorial posterior.

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

  1. Proporcionar una interfaz que permita al visitante escribir sus credenciales.
  2. Determinar si las credenciales enviadas son válidas.
  3. Iniciar la sesión del usuario creando el vale de autenticación de formularios.

Creación de 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.

Add a New ASP.NET Page Named Login.aspx

Figura 08: Agregar una nueva página de ASP.NET denominada Login.aspx (haga clic para ver la imagen a 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 y 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 TextBoxes a Login.aspx y establezca sus propiedades de id. en UserName y Password, respectivamente. Establezca también la propiedad TextMode de Password en Password. A continuación, agregue un control CheckBox y establezca su propiedad de id. en RememberMe y su propiedad Text en Recordarme. Después, agregue un botón denominado LoginButton cuya propiedad Text esté establecida en Login. Y, por último, agregue un control web Label y establezca su propiedad ID en InvalidCredentialsMessage, su propiedad Text en Su nombre de usuario o contraseña no es válida. Inténtelo de nuevo. Su propiedad ForeColor a Red 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="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Login.aspx.vb" 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>

The Login Page Contains Two TextBoxes, a CheckBox, a Button, and a Label

Figura 09: La página de inicio de sesión contiene dos TextBoxes, una CheckBox, un Button y una Label (haga clic para ver la imagen a tamaño completo).

Por último, cree un controlador de eventos para el evento Click de LoginButton. En el Diseñador, haga doble clic en el control de 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 de Button, 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ía el almacén de usuarios en una base de datos creando una tabla denominada Users 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 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 SqlMembershipProvider, no podemos usar el método ValidateUser de la clase Membership en este momento.

En lugar de tomarnos el tiempo para crear nuestra propia tabla de base de datos Users personalizada (que quedarí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 Sub LoginButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles LoginButton.Click
 ' Three valid username/password pairs: Scott/password, Jisun/password, and Sam/password.
 Dim users() As String = {"Scott", "Jisun", "Sam"}
 Dim passwords() As String = {"password", "password", "password"}
 For i As Integer = 0 To users.Length - 1
 Dim validUsername As Boolean = (String.Compare(UserName.Text, users(i), True) = 0)
 Dim validPassword As Boolean = (String.Compare(Password.Text, passwords(i), False) = 0)
 If validUsername AndAlso validPassword Then
 ' TODO: Log in the user...
 ' TODO: Redirect them to the appropriate page
 End If
 Next
 ' If we reach here, the user's credentials were invalid
 InvalidCredentialsMessage.Visible = True
End Sub

Como puede ver, hay tres cuentas de usuario válidas (Scott, Jisun y Sam) y las tres tienen la misma contraseña (password). 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 la 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 se le redirigirá a la página adecuada. Sin embargo, ¿cuál es la página adecuada? Recuerde que cuando un usuario visita una página que no está autorizado para ver, FormsAuthenticationModule le 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 le 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 por voluntad propia. En ese caso, después de iniciar sesión en el usuario, deben enviarse a la página de 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 vale de autenticación de formularios, con lo que se inicia sesión en el usuario en el sitio. La clase FormsAuthentication del espacio de nombres System.Web.Security proporciona métodos ordenados para iniciar 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. A continuación, este método agrega la cookie devuelta por GetAuthCookie a la colección Cookies (suponiendo que se use la autenticación de formularios basados en cookies; de lo contrario, este método llama a una clase interna que controla la lógica del vale 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 vale 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 Cookies, pero no desea redirigir al usuario a la página adecuada. Quizás quiera mantenerlo en la página de inicio de sesión o enviarlo a alguna página alternativa.

Puesto que queremos iniciar sesión en el usuario y redirigirle 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 vale de autenticación de formularios, usamos la propiedad TextBox de UserName para el parámetro username del vale de autenticación de formularios y el estado comprobado del CheckBox RememberMe para el parámetro persistCookie.

Para probar la página de inicio de sesión, visítela en un explorador. Para empezar, escriba credenciales no válidas, como el nombre de usuario Nope y la contraseña wrong. Al hacer clic en el botón Iniciar sesión, se producirá un postback y se mostrará la etiqueta InvalidCredentialsMessage.

The InvalidCredentialsMessage Label is Displayed When Entering Invalid Credentials

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

A continuación, escriba credenciales válidas y haga clic en el botón Iniciar sesión. Esta vez, cuando se produce el postback, se crea un vale de autenticación de formularios y se le redirige automáticamente de vuelta a Default.aspx. En este punto ha iniciado sesión en el sitio web, aunque no hay señales visuales que indiquen que tiene la sesión iniciada. 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.

En el paso 5 se examinan las técnicas para cerrarle la sesión de la página a un usuario.

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 acceda al tráfico de red puede ver el nombre de usuario y la contraseña. Para evitarlo, es esencial que se cifre 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 confidencial, solo tendrá que 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 conexión 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 manipulaciones). En el tutorial siguiente se presenta una explicación más exhaustiva sobre la seguridad de vales 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 un sitio web de este tipo, 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 es 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, agregue dos controles Panel, uno denominado AuthenticatedMessagePanel y el otro, AnonymousMessagePanel. Agregue un control Label denominado WelcomeBackMessage en el primer panel. En el segundo panel, agregue un control HyperLink, establezca su propiedad Text en Log In y su propiedad NavigateUrl en ~/Login.aspx. En este momento, el marcado declarativo de Default.aspx debe tener un aspecto similar al siguiente:

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Default.aspx.vb" 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 ya habrá adivinado, la idea aquí es mostrar solo AuthenticatedMessagePanel a los visitantes autenticados y solo AnonymousMessagePanel a los visitantes anónimos. Para ello, es necesario establecer las propiedades Visible de estos 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 Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 If Request.IsAuthenticated Then
 WelcomeBackMessage.Text = "Welcome back!"
 AuthenticatedMessagePanel.Visible = True
 AnonymousMessagePanel.Visible = False
 Else
 AuthenticatedMessagePanel.Visible = False
 AnonymousMessagePanel.Visible = True
 End If
End Sub

Con este código aplicado, 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 Welcome back! (vea la figura 12).

When Visiting Anonymously, a Log In Link is Displayed

Figura 11: Al visitar de forma anónima, se muestra un vínculo de inicio de sesión (haga clic para ver la imagen a tamaño completo).

Authenticated Users are Shown the Welcome back! Message

Figura 12: Los usuarios autenticados reciben el mensaje Welcome back! Mensaje (Haga clic para ver la imagen a tamaño completo.)

Podemos determinar la identidad del usuario que tiene la sesión iniciada mediante 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 de entidad de seguridad (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:

Dim currentUsersName As String = 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.

Lo importante 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) sea 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:

Dim ident As FormsIdentity = CType(User.Identity, FormsIdentity)

Dim authTicket As FormsAuthenticationTicket = 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, nombre de usuario!

WelcomeBackMessage.Text = "Welcome back, " & User.Identity.Name & "!"

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

The Welcome Message Includes the Currently Logged In User's Name

Figura 13: El mensaje de bienvenida incluye el nombre del usuario que ha iniciado sesión actualmente (haga clic para ver la imagen a tamaño completo).

Uso de los controles LoginView y LoginName

Mostrar contenido diferente para usuarios autenticados y anónimos es un requisito común, así como lo es mostrar el nombre del usuario que tiene la sesión iniciada. 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 marcado 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. Los motivos de esta decisión se expondrán 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. Basta con que arrastre un control ContentPlaceHolder desde el cuadro de herramientas a la vista Origen, colocando el marcado resultante justo encima del texto TODO: Menu will go here.

<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 ContentPlaceHolder de LoginContent. El contenido colocado en los controles ContentPlaceHolder de la página maestra se considera contenido predeterminado para ContentPlaceHolder. Es decir, las páginas ASP.NET 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.

The LoginView Control in the Toolbox

Figura 14: El control LoginView en el cuadro de herramientas (haga clic para ver la imagen a tamaño completo).

A continuación, agregue dos elementos <br /> inmediatamente después del control LoginView, pero dentro de ContentPlaceHolder. En este punto, el marcado del elemento <div> de navegación 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 desde el marcado declarativo. En 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 Log In 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 LoggedInTemplate y colóquelo inmediatamente después del texto "Welcome back, ". El control LoginName, como su nombre indica, muestra el nombre del usuario que tiene iniciada la sesión. Internamente, el control LoginName solo 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 la visita a través de un explorador. El mensaje Welcome back, 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 otra vez en el área de contenido de Default.aspx (a través de los controles Panel y de la lógica de programación).

The LoginView Control Displays Welcome back, Jisun.

Figura 15: El control LoginView muestra Welcome back, Jisun. (Haga clic para ver la imagen a tamaño completo.)

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 queramos 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 estaría fuera de 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 a Diseñador. Dado que no hemos definido explícitamente un control Content en Login.aspx para ContentPlaceHolder de LoginContent en 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: ContentPlaceHolder de LoginContent muestra el marcado predeterminado (el control LoginView).

The Login Page Shows the Default Content for the Master Page's LoginContent ContentPlaceHolder

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

Para invalidar el marcado predeterminado para ContentPlaceHolder de LoginContent, 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. (Al usar 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 Content recién creado. Si usa Visual Studio 2008, después de crear el control Content, 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 ni Welcome back, nombre de usuario en el <div> de navegación izquierdo, como sí sucede al visitar Default.aspx.

The Login Page Hides the Default LoginContent ContentPlaceHolder's Markup

Figura 17: La página de inicio de sesión oculta el marcado predeterminado de ContentPlaceHolder de LoginContent (haga clic para ver la imagen a 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 la sesión de un usuario. Además de los métodos para iniciar la sesión de un usuario, la clase FormsAuthentication también proporciona un método SignOut. El método SignOut simplemente destruye el vale de autenticación de formularios y, en consecuencia, cierra la sesión del usuario del 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, en función del estado de autenticación del usuario. Un LinkButton Login se representa para los usuarios anónimos, mientras que se muestra un LinkButton Logout para los usuarios autenticados. El texto de los LinkButtons Login y Logout se puede configurar a través de las propiedades LoginText y LogoutText de LoginStatus.

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

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

Puede que tenga curiosidad por saber por qué se realiza aquí un redireccionamiento. Si el usuario quiere permanecer en la misma página, ¿por qué necesita el redireccionamiento explícito? El motivo es que cuando se hace clic en el LinkButton Logoff, el usuario sigue teniendo el vale 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. Para 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.

  • Redirect: se redirige al usuario a la dirección URL especificada por la propiedad LogoutPageUrl de LoginStatus.
  • RedirectToLoginPage: se redirige al usuario 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 Redireccionamiento para enviar al usuario a una página que muestre un mensaje que confirme que se ha cerrado la sesión. Empiece creando una página en el directorio raíz denominada Logout.aspx. No olvide asociar esta página a la página maestra Site.master. A continuación, escriba un mensaje en el marcado de la página que explique al usuario que se ha cerrado su 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á tanto para los usuarios anónimos como para los autenticados, pero no pasa nada porque LoginStatus mostrará correctamente un LinkButton Login o Logout. Con la adición del control LoginStatus, el HyperLink Iniciar sesión de AnonymousTemplate es superfluo, así que puede quitarlo.

En la figura 18 se muestra Default.aspx cuando Jisun la visita. Tenga en cuenta que la columna izquierda muestra el mensaje Welcome back, Jisun junto con un vínculo para cerrar sesión. Al hacer clic en el LinkButton de cierre de sesión, se produce un postback, se cierra la sesión de Jisun y se le redirige a Logout.aspx. Como se muestra en la figura 19, en el momento en que Jisun llega a Logout.aspx, ya se ha cerrado la sesión y, por tanto, es anónima. Por lo tanto, la columna izquierda muestra el texto Welcome, stranger y un vínculo a la página de inicio de sesión.

Default.aspx Shows Welcome Back, Jisun Along with a Logout LinkButton

Figura 18: Default.aspx muestra Welcome back, Jisun junto con un LinkButton Logout (haga clic para ver la imagen a tamaño completo).

Logout.aspx Shows Welcome, stranger Along with a Login LinkButton

Figura 19: Logout.aspx muestra Welcome, stranger junto con un LinkButton Login (haga clic para ver la imagen a tamaño completo).

Nota:

Le animo a que personalice la página Logout.aspx para ocultar el elemento ContentPlaceHolder LoginContent de la página maestra (como hicimos para Login.aspx en el paso 4). El motivo es que el LinkButton Login representado 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, que pasa la dirección URL actual en el parámetro querystring de ReturnUrl. En resumen, si un usuario que ha cerrado la sesión hace clic en el LinkButton Login de LoginStatus y luego inicia sesión, se le redirigirá de nuevo a Logout.aspx, lo que podría confundirlo fácilmente.

Resumen

En este tutorial comenzamos con un examen del flujo de trabajo de autenticación de formularios y luego pasamos a implementar la autenticación de formularios en una aplicación 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 a los 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 más compatibilidad mediante programación para determinar si una solicitud está autenticada, así como información sobre la identidad del usuario. También están los controles web LoginView, LoginStatus y LoginName, 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 tutoriales futuros.

En este tutorial se proporciona información general sobre la autenticación de formularios. No examinamos las opciones de configuración ordenadas, ni analizamos cómo funcionan los vales de autenticación de formularios sin cookies, ni exploramos cómo ASP.NET protege el contenido del vale de autenticación de formularios. Analizaremos estos temas y mucho más en el siguiente tutorial.

¡Feliz programación!

Lecturas adicionales

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

Entrenamiento en vídeo sobre temas incluidos en este tutorial

Acerca del autor

Scott Mitchell, autor de varios 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 in 24 Hours. Se puede contactar con Scott en mitchell@4guysfromrolla.com o a través de su blog en http://ScottOnWriting.NET.

Agradecimientos especiales a

Esta serie de tutoriales fue revisada por muchos revisores de gran ayuda. Entre los revisores principales de este tutorial están Alicja Maziarz, John Suru y Teresa Murphy. ¿Le interesa leer mis próximos artículos de MSDN? Si es así, escríbame a mitchell@4guysfromrolla.com.