Agregar ASP.NET identidad a un proyecto de formularios web vacíos o existentes

En este tutorial se muestra cómo agregar ASP.NET Identity (el nuevo sistema de pertenencia para ASP.NET) a una aplicación de ASP.NET.

Al crear un nuevo proyecto de Web Forms o MVC en Visual Studio 2017 RTM con cuentas individuales, Visual Studio instalará todos los paquetes necesarios y agregará todas las clases necesarias automáticamente. En este tutorial se muestran los pasos para agregar ASP.NET compatibilidad con identidades al proyecto de Web Forms existente o a un nuevo proyecto vacío. Describiré todos los paquetes NuGet que necesita instalar y las clases que necesita agregar. Voy a repasar los formularios web de ejemplo para registrar nuevos usuarios e iniciar sesión, al mismo tiempo que se resaltan todas las API de punto de entrada principales para la administración y la autenticación de usuarios. En este ejemplo se usará la implementación predeterminada de ASP.NET Identity para el almacenamiento de datos SQL, que se basa en Entity Framework. En este tutorial, usaremos LocalDB para la base de datos SQL.

Introducción a ASP.NET Identity

  1. Empiece por instalar y ejecutar Visual Studio 2017.

  2. Seleccione Nuevo proyecto en la página Inicio, o bien puede usar el menú y seleccionar Archivo y, a continuación, Nuevo proyecto.

  3. En el panel izquierdo, expanda Visual C#, seleccione Web y , a continuación, ASP.NET Aplicación web (.Net Framework) . Asigne al proyecto el nombre "WebFormsIdentity" y seleccione Aceptar.

    Imagen que muestra la creación de un nuevo proyecto

  4. En el cuadro de diálogo Nuevo ASP.NET proyecto , seleccione la plantilla Vacía .

    Ventana de diálogo de nuevo proyecto A S P punto N E T

    Observe que el botón Cambiar autenticación está deshabilitado y no se proporciona compatibilidad con la autenticación en esta plantilla. Las plantillas de Web Forms, MVC y API web le permiten seleccionar el enfoque de autenticación.

Adición de paquetes de identidad a la aplicación

En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet. Busque e instale el paquete Microsoft.AspNet.Identity.EntityFramework .

Imagen que ilustra cómo acceder a la administración de paquetes Nu Get

Tenga en cuenta que este paquete instalará los paquetes de dependencia: EntityFramework y Microsoft ASP.NET Identity Core.

Agregar un formulario web para registrar usuarios

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Agregar y, a continuación, formulario web.

    Imagen que muestra cómo agregar un formulario web a los usuarios registrados

  2. En el cuadro de diálogo Especificar nombre para elemento, asigne al nuevo formulario web el nombre Register y, a continuación, seleccione Aceptar.

  3. Reemplace el marcado en el archivo Register.aspx generado con el código siguiente. Los cambios de código se resaltan.

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="WebFormsIdentity.Register" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
        <form id="form1" runat="server">
        <div>
            <h4 style="font-size: medium">Register a new user</h4>
            <hr />
            <p>
                <asp:Literal runat="server" ID="StatusMessage" />
            </p>                
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="UserName" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="Password" TextMode="Password" />                
                </div>
            </div>
            <div style="margin-bottom:10px">
                <asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
                <div>
                    <asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />                
                </div>
            </div>
            <div>
                <div>
                    <asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" />
                </div>
            </div>
        </div>
        </form>
    </body>
    </html>
    

    Nota:

    Esta es simplemente una versión simplificada del archivo de Register.aspx que se crea al crear un nuevo proyecto de ASP.NET Web Forms. El marcado anterior agrega campos de formulario y un botón para registrar un nuevo usuario.

  4. Abra el archivo Register.aspx.cs y reemplace el contenido del archivo por el código siguiente:

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using System;
    using System.Linq;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
    
             var user = new IdentityUser() { UserName = UserName.Text };
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                StatusMessage.Text = string.Format("User {0} was created successfully!", user.UserName);
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    Nota:

    1. El código anterior es una versión simplificada del archivo de Register.aspx.cs que se crea al crear un nuevo proyecto ASP.NET Web Forms.
    2. La clase IdentityUser es la implementación predeterminada de EntityFramework de la interfaz IUser . La interfaz IUser es la interfaz mínima para un usuario en ASP.NET Identity Core.
    3. La clase UserStore es la implementación predeterminada de EntityFramework de un almacén de usuarios. Esta clase implementa las interfaces mínimas de ASP.NET Identity Core: IUserStore, IUserLoginStore, IUserClaimStore e IUserRoleStore.
    4. La clase UserManager expone las API relacionadas con el usuario que guardarán automáticamente los cambios en userStore.
    5. La clase IdentityResult representa el resultado de una operación de identidad.
  5. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Agregar, Agregar ASP.NET carpeta y , a continuación, App_Data.

    Ilustración de cómo agregar datos de aplicación

  6. Abra el archivo Web.config y agregue una entrada de cadena de conexión para la base de datos que usaremos para almacenar información de usuario. EntityFramework creará la base de datos en tiempo de ejecución para las entidades Identity. La cadena de conexión es similar a una creada automáticamente al crear un nuevo proyecto de Web Forms. El código resaltado muestra la marcación que debe agregar:

    <?xml version="1.0" encoding="utf-8"?>
    <!--
      For more information on how to configure your ASP.NET application, please visit
      https://go.microsoft.com/fwlink/?LinkId=169433
      -->
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit https://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
       <connectionStrings>
          <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\WebFormsIdentity.mdf;Initial Catalog=WebFormsIdentity;Integrated Security=True"
                providerName="System.Data.SqlClient" />
       </connectionStrings>
      <system.web>
        <compilation debug="true" targetFramework="4.5" />
        <httpRuntime targetFramework="4.5" />
      </system.web>
      <entityFramework>
        <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
          <parameters>
            <parameter value="v11.0" />
          </parameters>
        </defaultConnectionFactory>
        <providers>
          <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
        </providers>
      </entityFramework>
    </configuration>
    

    Nota:

    Para Visual Studio 2015 o superior, reemplace (localdb)\v11.0 por (localdb)\MSSQLLocalDB en su cadena de conexión.

  7. Haga clic con el botón derecho en el archivo Register.aspx en el proyecto y seleccione Establecer como página de inicio. Presione Ctrl + F5 para compilar y ejecutar la aplicación web. Escriba un nuevo nombre de usuario y una contraseña y, a continuación, seleccione Registrar.

    Imagen exitosa de registro de nuevo usuario

    Nota:

    ASP.NET Identity admite la validación y, en este ejemplo, puede comprobar el comportamiento predeterminado en los validadores de usuario y contraseña que proceden del paquete Identity Core. El validador predeterminado de User (UserValidator) tiene una propiedad AllowOnlyAlphanumericUserNames que tiene el valor predeterminado establecido en true. El validador predeterminado para Contraseña (MinimumLengthValidator) garantiza que la contraseña tenga al menos 6 caracteres. Estos validadores son propiedades en UserManager que se pueden invalidar si desea tener validación personalizada,

Comprobación de la base de datos y tablas de Identidad de LocalDb generadas por Entity Framework

  1. En el menú Ver , seleccione Explorador de servidores.

    Imagen de cómo acceder al Explorador de servidores

  2. Expanda DefaultConnection (WebFormsIdentity), expanda Tablas, haga clic con el botón derecho en AspNetUsers y, a continuación, seleccione Mostrar datos de tabla.

    Imagen de cómo obtener acceso a mostrar datos de tabla
    Imagen que muestra los datos de tabla de los usuarios registrados

Configuración de la aplicación para la autenticación OWIN

En este momento solo se ha agregado compatibilidad con la creación de usuarios. Ahora, vamos a demostrar cómo podemos agregar autenticación para iniciar sesión de un usuario. ASP.NET Identity usa el middleware de autenticación de Microsoft OWIN para la autenticación de formularios. La autenticación de cookies OWIN es un mecanismo de autenticación basado en cookies y notificaciones que cualquier marco hospedado en OWIN o IIS puede usar. Con este modelo, se pueden usar los mismos paquetes de autenticación en varios marcos, como ASP.NET MVC y Web Forms. Para obtener más información sobre el proyecto Katana y cómo ejecutar middleware en un host independiente, consulte Introducción al proyecto Katana.

Instalación de paquetes de autenticación en la aplicación

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto y seleccione Administrar paquetes NuGet. Busque e instale el paquete Microsoft.AspNet.Identity.Owin .

    Imagen del administrador de paquetes Nu Get

  2. Busque e instale el paquete Microsoft.Owin.Host.SystemWeb .

    Nota:

    El paquete Microsoft.Aspnet.Identity.Owin contiene un conjunto de clases de extensión de OWIN para administrar y configurar el middleware de autenticación de OWIN que será utilizado por los paquetes de ASP.NET Identity Core. El paquete Microsoft.Owin.Host.SystemWeb contiene un servidor OWIN que permite que las aplicaciones basadas en OWIN se ejecuten en IIS mediante la canalización de solicitudes de ASP.NET. Para obtener más información, consulte Middleware de OWIN en la canalización integrada de IIS.

Adición de clases de configuración de inicio y autenticación de OWIN

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto, seleccione Agregar y, después, Agregar nuevo elemento. En el cuadro de diálogo de texto de búsqueda, escriba "owin". Asigne un nombre a la clase "Startup" y seleccione Agregar.

    Imagen de la ventana Agregar nuevo elemento

  2. En el archivo Startup.cs, agregue el código resaltado que se muestra a continuación para configurar la autenticación de cookies de OWIN.

    using Microsoft.AspNet.Identity;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Owin;
    
    [assembly: OwinStartup(typeof(WebFormsIdentity.Startup))]
    
    namespace WebFormsIdentity
    {
       public class Startup
       {
          public void Configuration(IAppBuilder app)
          {
             // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
             app.UseCookieAuthentication(new CookieAuthenticationOptions
             {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Login")
             });
          }
       }
    }
    

    Nota:

    Esta clase contiene el OwinStartup atributo para especificar la clase de inicio de OWIN. Cada aplicación OWIN tiene una clase de inicio donde se especifican componentes para la canalización de la aplicación. Consulte Detección de clases de inicio de OWIN para obtener más información sobre este modelo.

Agregar formularios web para registrar e iniciar sesión de usuarios

  1. Abra el archivo Register.aspx.cs y agregue el código siguiente que inicia la sesión del usuario cuando el registro se realiza correctamente.

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Linq;
    using System.Web;
    
    namespace WebFormsIdentity
    {
       public partial class Register : System.Web.UI.Page
       {
          protected void CreateUser_Click(object sender, EventArgs e)
          {
             // Default UserStore constructor uses the default connection string named: DefaultConnection
             var userStore = new UserStore<IdentityUser>();
             var manager = new UserManager<IdentityUser>(userStore);
             var user = new IdentityUser() { UserName = UserName.Text };
    
             IdentityResult result = manager.Create(user, Password.Text);
    
             if (result.Succeeded)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
                authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusMessage.Text = result.Errors.FirstOrDefault();
             }
          }
       }
    }
    

    Nota:

    • Dado que ASP.NET Identity y OWIN Cookie Authentication son sistema basado en notificaciones, el marco requiere que el desarrollador de la aplicación genere claimsIdentity para el usuario. ClaimsIdentity tiene información sobre todas las reclamaciones del usuario, como a qué roles pertenece el usuario. También puede agregar más atributos para el usuario en esta fase.
    • Puede iniciar sesión en el usuario mediante el AuthenticationManager de OWIN llamando a SignIn y pasando la instancia de ClaimsIdentity como se muestra anteriormente. Este código también iniciará sesión en el usuario y generará una cookie. Esta llamada es análoga a FormAuthentication.SetAuthCookie usada por el módulo FormsAuthentication .
  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto, seleccione Agregar y, después, Formulario web. Nombre al formulario web Inicio de sesión.

    Imagen que agrega un nuevo formulario web

  3. Reemplace el contenido del archivo Login.aspx por el código siguiente:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="WebFormsIdentity.Login" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
       <title></title>
    </head>
    <body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
       <form id="form1" runat="server">
          <div>
             <h4 style="font-size: medium">Log In</h4>
             <hr />
             <asp:PlaceHolder runat="server" ID="LoginStatus" Visible="false">
                <p>
                   <asp:Literal runat="server" ID="StatusText" />
                </p>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LoginForm" Visible="false">
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="UserName" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
                   <div>
                      <asp:TextBox runat="server" ID="Password" TextMode="Password" />
                   </div>
                </div>
                <div style="margin-bottom: 10px">
                   <div>
                      <asp:Button runat="server" OnClick="SignIn" Text="Log in" />
                   </div>
                </div>
             </asp:PlaceHolder>
             <asp:PlaceHolder runat="server" ID="LogoutButton" Visible="false">
                <div>
                   <div>
                      <asp:Button runat="server" OnClick="SignOut" Text="Log out" />
                   </div>
                </div>
             </asp:PlaceHolder>
          </div>
       </form>
    </body>
    </html>
    
  4. Reemplace el contenido del archivo Login.aspx.cs por lo siguiente:

    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.EntityFramework;
    using Microsoft.Owin.Security;
    using System;
    using System.Web;
    using System.Web.UI.WebControls;
    
    namespace WebFormsIdentity
    {
       public partial class Login : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
             if (!IsPostBack)
             {
                if (User.Identity.IsAuthenticated)
                {
                   StatusText.Text = string.Format("Hello {0}!!", User.Identity.GetUserName());
                   LoginStatus.Visible = true;
                   LogoutButton.Visible = true;
                }
                else
                {
                   LoginForm.Visible = true;
                }
             }
          }
    
          protected void SignIn(object sender, EventArgs e)
          {
             var userStore = new UserStore<IdentityUser>();
             var userManager = new UserManager<IdentityUser>(userStore);
             var user = userManager.Find(UserName.Text, Password.Text);
    
             if (user != null)
             {
                var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
                var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
    
                authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
                Response.Redirect("~/Login.aspx");
             }
             else
             {
                StatusText.Text = "Invalid username or password.";
                LoginStatus.Visible = true;
             }
          }
    
          protected void SignOut(object sender, EventArgs e)
          {
             var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
             authenticationManager.SignOut();
             Response.Redirect("~/Login.aspx");
          }
       }
    }
    

    Nota:

    • Ahora Page_Load comprueba el estado del usuario actual y realiza acciones en función de su Context.User.Identity.IsAuthenticated estado. Mostrar nombre de usuario que ha iniciado sesión : Microsoft ASP.NET Identity Framework ha agregado métodos de extensión en System.Security.Principal.IIdentity que le permiten obtener el UserName y el UserId para el usuario que ha iniciado sesión. Estos métodos de extensión se definen en el Microsoft.AspNet.Identity.Core ensamblaje. Estos métodos de extensión son el reemplazo de HttpContext.User.Identity.Name .
    • Método SignIn: This el método reemplaza el método anterior CreateUser_Click en este ejemplo y ahora inicia sesión en el usuario después de crear correctamente el usuario.
      Microsoft OWIN Framework ha agregado métodos de extensión en System.Web.HttpContext que permiten obtener una referencia a un IOwinContext. Estos métodos de extensión se definen en el ensamblaje Microsoft.Owin.Host.SystemWeb. La OwinContext clase expone una IAuthenticationManager propiedad que representa la funcionalidad de middleware de autenticación disponible en la solicitud actual. Puede iniciar sesión al usuario utilizando el AuthenticationManager desde OWIN y llamar a SignIn, pasando el ClaimsIdentity tal como se muestra anteriormente. Dado que ASP.NET Identity y OWIN Cookie Authentication son sistemas basados en reclamaciones, el marco requiere que la aplicación genere un ClaimsIdentity para el usuario. ClaimsIdentity tiene información sobre todas las atribuciones del usuario, como sus roles. También puede agregar más reclamaciones para el usuario en esta fase. Este código iniciará al usuario sesión y generará una cookie. Esta llamada es análoga a FormAuthentication.SetAuthCookie usada por el módulo FormsAuthentication .
    • SignOut method: obtiene una referencia a AuthenticationManager desde OWIN y llama a SignOut. Esto es análogo al método FormsAuthentication.SignOut usado por el módulo FormsAuthentication .
  5. Presione Ctrl + F5 para compilar y ejecutar la aplicación web. Escriba un nuevo nombre de usuario y una contraseña y, a continuación, seleccione Registrar.

    Imagen del nuevo registro de usr
    Nota: En este momento, el nuevo usuario se crea e inicia sesión.

  6. Seleccione el botón Cerrar sesión . Se le redirigirá al formulario Iniciar sesión.

  7. Escriba un nombre de usuario o una contraseña no válidos y seleccione el botón Iniciar sesión . El UserManager.Find método devolverá null y se mostrará el mensaje de error " Nombre de usuario o contraseña no válidos ".

    Imagen del intento de inicio de sesión no válido