Agregar ASP.NET Identity a un proyecto de formularios Web Forms vacío o existente
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 la compatibilidad de ASP.NET Identity al proyecto de Web Forms existente o a un nuevo proyecto vacío. Describiré todos los paquetes NuGet que necesitas instalar y las clases que necesitas agregar. Voy a repasar los Web Forms 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.
Empieza con ASP.NET Identity
Empieza por instalar y ejecutar Visual Studio 2017.
Selecciona Nuevo proyecto en la página Inicio, o bien puedes usar el menú y seleccionar Archivo y, a continuación, Nuevo proyecto.
En el panel izquierdo, expande Visual C#, selecciona Web y, a continuación, ASP.NET Aplicación web (.Net Framework). Asigna al proyecto el nombre "WebFormsIdentity" y selecciona Aceptar.
En el cuadro de diálogo Nuevo proyecto ASP.NET, selecciona la plantilla Vacía.
Observa 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 Web API te permiten seleccionar el enfoque de autenticación.
Adición de paquetes de identidad a la aplicación
En el Explorador de soluciones, haz clic con el botón derecho en Administrar paquetes NuGet. Busca e instala el paquete Microsoft.AspNet.Identity.EntityFramework.
Ten en cuenta que este paquete instalará los paquetes de dependencia: EntityFramework y Microsoft ASP.NET Identity Core.
Agregar un formulario web para registrar usuarios
En el Explorador de soluciones, haz clic con el botón derecho en el proyecto y selecciona Agregar y, a continuación, Web Form.
En el cuadro de diálogo Especificar nombre para elemento, asigna al nuevo formulario web el nombre Register y, a continuación, selecciona Aceptar
Reemplaza el marcado en el archivo Register.aspx generado por el código siguiente. Los cambios de código aparecen resaltados.
<%@ 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 Register.aspx que se crea al crear un nuevo proyecto ASP.NET Web Forms. El marcado anterior agrega campos de formulario y un botón para registrar un nuevo usuario.
Abre el archivo Register.aspx.cs y reemplaza 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:
- El código anterior es una versión simplificada del archivo Register.aspx.cs que se crea al crear un nuevo proyecto de Web Forms de ASP.NET.
- 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.
- 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.
- La clase UserManager expone API relacionadas con el usuario que guardarán automáticamente los cambios en UserStore.
- La clase IdentityResult representa el resultado de una operación de identidad.
En el Explorador de soluciones, haz clic con el botón derecho en el proyecto y selecciona Agregar, Agregar carpeta ASP.NET y, a continuación, App_Data.
Abre el archivo Web.config y agrega 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 el marcado que debes 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, reemplaza
(localdb)\v11.0
por(localdb)\MSSQLLocalDB
en la cadena de conexión.Haz clic con el botón derecho en el archivo Register.aspx en el proyecto y selecciona Establecer como página de inicio. Presione Ctrl + F5 para compilar y ejecutar la aplicación web. Escribe un nuevo nombre de usuario y una contraseña y, a continuación, selecciona Registrar.
Nota:
ASP.NET Identity admite la validación y, en este ejemplo, puedes comprobar el comportamiento predeterminado en los validadores de usuario y contraseña que proceden del paquete Identity Core. El validador predeterminado para Usuario (
UserValidator
) tiene una propiedadAllowOnlyAlphanumericUserNames
que tiene el valor predeterminado establecido entrue
. El validador predeterminado para Contraseña (MinimumLengthValidator
) garantiza que la contraseña tenga al menos 6 caracteres. Estos validadores son propiedades enUserManager
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
En el menú Ver, selecciona Explorador de servidores.
Expande DefaultConnection (WebFormsIdentity), expande Tablas, haz clic con el botón derecho en AspNetUsers y, a continuación, selecciona Mostrar los datos de la tabla.
Configuración de la aplicación para la autenticación OWIN
En este momento solo hemos añadido compatibilidad con la creación de usuarios. Ahora, vamos a demostrar cómo podemos agregar la autenticación para el inicio de 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, consulta Introducción al proyecto Katana.
Instalación de paquetes de autenticación en la aplicación
En el Explorador de soluciones, haz clic con el botón derecho en Administrar paquetes NuGet. Busca e instala el paquete Microsoft.AspNet.Identity.Owin.
Busca e instala el paquete Microsoft.Owin.Host.SystemWeb.
Nota:
El paquete Microsoft.Aspnet.Identity.Owin contiene un conjunto de clases de extensión OWIN para administrar y configurar el middleware de autenticación de OWIN que los paquetes de ASP.NET Identity Core usan. 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, consulta Middleware de OWIN en la canalización integrada de IIS.
Adición de clases de configuración de inicio y autenticación de OWIN
En el Explorador de soluciones, haz clic con el botón derecho en el proyecto, selecciona Agregar y, después, Agregar nuevo elemento. En el cuadro de texto de búsqueda, escribe "owin". Asigna un nombre a la clase "Startup" y selecciona Agregar.
En el archivo Startup.cs, agrega 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 atributo
OwinStartup
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. Consulta 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
Abre el archivo Register.aspx.cs y agrega 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 un sistema basado en notificaciones, el marco requiere que el desarrollador de la aplicación genere un ClaimsIdentity para el usuario. ClaimsIdentity tiene información sobre todas las notificaciones del usuario, como a qué roles pertenece el usuario. También puede agregar más notificaciones para el usuario en esta fase.
- Puedes iniciar sesión en el usuario mediante AuthenticationManager desde OWIN y llamando a
SignIn
y pasando en 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.
En el Explorador de soluciones, haz clic con el botón derecho en el proyecto, selecciona Agregar y, después, Web Form. Asigna un nombre al inicio de sesión del formulario web.
Reemplaza 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>
Reemplaza el contenido del archivo Login.aspx.cs con 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 estadoContext.User.Identity.IsAuthenticated
. Mostrar nombre de usuario registrado: Microsoft ASP.NET Identity Framework ha agregado métodos de extensión en System.Security.Principal.IIdentity que te permite obtener elUserName
y elUserId
para el usuario que ha iniciado sesión. Estos métodos de extensión se definen en el ensambladoMicrosoft.AspNet.Identity.Core
. Estos métodos de extensión son el reemplazo de HttpContext.User.Identity.Name. - Método SignIn:
This
método reemplaza el método anteriorCreateUser_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 enSystem.Web.HttpContext
que te permite obtener una referencia aIOwinContext
. Estos métodos de extensión se definen en el ensambladoMicrosoft.Owin.Host.SystemWeb
. La claseOwinContext
expone una propiedadIAuthenticationManager
que representa la funcionalidad de middleware de autenticación disponible en la solicitud actual. Puedes iniciar sesión con el usuarioAuthenticationManager
desde OWIN y llamando aSignIn
y pasando enClaimsIdentity
como se muestra anteriormente. Dado que ASP.NET Identity y OWIN Cookie Authentication son sistemas basados en notificaciones, el marco requiere que la aplicación genere unClaimsIdentity
para el usuario.ClaimsIdentity
tiene información sobre todas las notificaciones del usuario, como los roles a los que pertenece el usuario. También puedes agregar más notificaciones para el usuario en esta fase. Este código iniciará sesión en el usuario y generará una cookie también. Esta llamada es análoga a FormAuthentication.SetAuthCookie usada por el módulo FormsAuthentication. - Método
SignOut
: obtiene una referencia aAuthenticationManager
desde OWIN y llama aSignOut
. Esto es análogo al método FormsAuthentication.SignOut usado por el módulo FormsAuthentication.
- Ahora
Presiona CTRL+F5 para compilar y ejecutar la aplicación web. Escribe un nuevo nombre de usuario y una contraseña y, a continuación, selecciona Registrar.
Nota: En este momento, se crea el nuevo usuario e inicia sesión.Selecciona el botón Cerrar sesión. Se te redirigirá al formulario Iniciar sesión.
Escribe un nombre de usuario o una contraseña no válidos y selecciona el botón Iniciar sesión. El método
UserManager.Find
devolverá null y se mostrará el mensaje de error "Nombre de usuario o contraseña no válidos".