Ejercicio: configuración de la compatibilidad con Identity

Completado

Identity funciona de fábrica sin ninguna personalización. En esta unidad, Identity se agrega a un proyecto existente de Razor Pages de ASP.NET Core.

Abrir el proyecto de inicio

Para usar la instancia de GitHub Codespaces recomendada, navegue hasta sus Codespaces para el repositorio MicrosoftDocs/mslearn-secure-aspnet-core-identity. Cree un nuevo codespace usando la rama main, y después pase a Explorar la aplicación.

Para usar un contenedor de desarrollo local, siga estos pasos:

  1. En una ventana de Visual Studio Code, presione F1 tecla para abrir la paleta de comandos. Busque y seleccione Contenedores de desarrollo: Clone Repository in Container Volume....

  2. Escriba la siguiente dirección URL del repositorio: https://github.com/MicrosoftDocs/mslearn-secure-aspnet-core-identity. Seleccione la rama main. Visual Studio Code crea el contenedor de desarrollo. Acepte las indicaciones para instalar las extensiones recomendadas.

  3. Omitir Explorar la aplicación.

Para usar un entorno de desarrollo local, siga estos pasos:

  1. En una ventana de terminal, ejecute el comando siguiente para obtener el proyecto de inicio:

    git clone https://github.com/MicrosoftDocs/mslearn-secure-aspnet-core-identity
    
  2. Cambie al directorio del código fuente e inicie Visual Studio Code:

    cd mslearn-secure-aspnet-core-identity
    code .
    

    Se abre Visual Studio Code. Acepte las indicaciones para instalar extensiones recomendadas, pero NO seleccione Volver a abrir en contenedor si se le solicita. Continúe con los pasos siguientes.

Explorar la aplicación

  1. Una vez cargado el proyecto, presione Ctrl+Mayús+` para abrir un panel de terminal nuevo.

  2. En el nuevo panel de terminal, establezca la ubicación en el directorio RazorPagesPizza :

    cd RazorPagesPizza
    
  3. En el panel Explorador, expanda el directorio RazorPagesPizza para ver el código. RazorPagesPizza es el directorio del proyecto. A medida que continúe, asuma que todas las rutas descritas en este módulo son relativas a esta ubicación.

    Ahora se ejecutará la aplicación para obtener una introducción rápida.

  4. En el panel de terminal, compile el proyecto y ejecute la aplicación:

    dotnet run
    
  5. Observe la dirección URL que se muestra en la salida del terminal. Por ejemplo: https://localhost:7192.

  6. Abra la aplicación en el explorador; para ello, seleccione la dirección URL con Ctrl+clic.

    Importante

    Si usa el contenedor de desarrollo en Docker local, el explorador no confiará en el certificado SSL desde dentro del contenedor. Para ver la aplicación web, debe realizar una de las acciones siguientes:

    • Omita el error del certificado. Si usa Microsoft Edge, seleccione Opciones avanzadas y Continuar a localhost (no recomendado). Los detalles varían según el explorador.
    • Guarde el certificado y agréguelo a las entidades de certificación de confianza.
    • Importe un certificado de desarrollo existente dentro del contenedor. Para obtener más información, vea los comentarios generados en ./devcontainer/devcontainter.json.
  7. Explore la aplicación web en el explorador. Con los vínculos del encabezado:

    1. Vaya a Pizza List
    2. Vuelva a Inicio.

    Observe que no tiene que autenticarse.

  8. Para detener la aplicación, presione Ctrl+C en el panel del terminal.

Adición de Identity de ASP.NET Core al proyecto

La implementación de Identity predeterminada se puede agregar con las herramientas de línea de comandos de dotnet.

  1. Instale el proveedor de scaffolding de código ASP.NET Core:

    dotnet tool install dotnet-aspnet-codegenerator --version 8.0.* --global
    

    El scaffolder es una herramienta de .NET que:

    • Se usa para agregar los componentes predeterminados de Identity al proyecto.
    • Habilita la personalización de los componentes de la interfaz de usuario de Identity en la unidad siguiente.
    • Se invoca a través de dotnet aspnet-codegenerator en este módulo.
  2. Agregue los siguientes paquetes NuGet al proyecto:

    dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design --version 8.0.*
    dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore --version 8.0.*
    dotnet add package Microsoft.AspNetCore.Identity.UI --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.Design --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 8.0.*
    dotnet add package Microsoft.EntityFrameworkCore.Tools --version 8.0.*
    

    Estos paquetes instalan plantillas y dependencias de generación de código que usa el proveedor de scaffolding.

    Sugerencia

    Para ver los generadores disponibles, haga lo siguiente:

    • En el shell de comandos, ejecute dotnet aspnet-codegenerator -h.
    • Cuando se encuentre en Visual Studio, haga clic con el botón derecho en Explorador de soluciones y seleccione Agregar>Nuevo elemento con scaffold.
  3. Use el proveedor de scaffolding para agregar los componentes de Identity predeterminados al proyecto. Ejecute el siguiente comando en el terminal:

    dotnet aspnet-codegenerator identity --useDefaultUI --dbContext RazorPagesPizzaAuth --userClass RazorPagesPizzaUser
    

    En el comando anterior:

    • El generador identificado como identity se usa para agregar el marco de identidad al proyecto.
    • La opción --useDefaultUI indica que se usa una biblioteca de clases de Razor (RCL) que contiene los elementos predeterminados de la interfaz de usuario. Bootstrap se usa para aplicar estilo a los componentes.
    • La opción --dbContext especifica el nombre de una clase de contexto de base de datos de EF Core que se va a generar.
    • La opción --userClass especifica el nombre de la clase de usuario que se va a generar. La clase de usuario predeterminada es IdentityUser, pero dado que la clase de usuario se extenderá en una unidad posterior, se especifica una clase de usuario personalizada denominada RazorPagesPizzaUser. La clase RazorPagesPizzaUser se deriva de IdentityUser.

    La siguiente estructura de directorios Areas aparece en el directorio RazorPagesPizza:

    • Areas
      • Identity (se muestra en la misma línea que Áreas)
        • Data
          • RazorPagesPizzaAuth.cs
          • RazorPagesPizzaUser.cs
        • Pages
          • _ValidationScriptsPartial.cshtml
          • _ViewStart.cshtml

    Sugerencia

    Si el directorio Areas no aparece automáticamente en el panel Explorador, seleccione el botón Actualizar explorador en el encabezado MSLEARN-SECURE-ASPNET-CORE-IDENTITY del panel Explorador.

    Las áreas proporcionan una manera de crear particiones de una aplicación web de ASP.NET Core en grupos funcionales más pequeños.

    El proveedor de scaffolding también ha realizado los cambios resaltados a continuación en Program.cs, con el formato modificado para mejorar la legibilidad:

    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;
    using RazorPagesPizza.Areas.Identity.Data;
    var builder = WebApplication.CreateBuilder(args);
    var connectionString = builder.Configuration.GetConnectionString("RazorPagesPizzaAuthConnection") 
        ?? throw new InvalidOperationException("Connection string 'RazorPagesPizzaAuthConnection' not found.");
    
    builder.Services.AddDbContext<RazorPagesPizzaAuth>(options => options.UseSqlServer(connectionString));
    
    builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<RazorPagesPizzaAuth>();
    
    // Add services to the container.
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    
    app.UseRouting();
    
    app.UseAuthorization();
    
    app.MapRazorPages();
    
    app.Run();
    

    En el código anterior:

    • La cadena de conexión RazorPagesPizzaAuthConnection se lee desde appsettings.json.
    • La clase de contexto de base de datos de EF Core, llamada RazorPagesPizzaAuth, se configura con la cadena de conexión.
    • Se registran los servicios de Identity, incluidos la interfaz de usuario predeterminada, los proveedores de tokens y la autenticación basada en cookies.
      • .AddDefaultIdentity<IdentityUser> indica a los servicios de Identity que usen el modelo de usuario predeterminado.
      • La expresión lambda options => options.SignIn.RequireConfirmedAccount = true especifica que los usuarios deben confirmar sus cuentas de correo electrónico.
      • .AddEntityFrameworkStores<RazorPagesPizzaAuth>() especifica que Identity usa el almacén predeterminado de Entity Framework Core para su base de datos. Se usa la clase RazorPagesPizzaAuthDbContext.

Configuración de la conexión de base de datos

La sección ConnectionStrings de appsettings.jsondebería tener un aspecto similar al código JSON siguiente:

"ConnectionStrings": {
    "RazorPagesPizzaAuthConnection": "Server=(localdb)\\mssqllocaldb;Database=RazorPagesPizza;Trusted_Connection=True;MultipleActiveResultSets=true"
}

Esta cadena de conexión apunta a una instancia de LocalDB de SQL Server Express de forma predeterminada. Si está desarrollando localmente, no haga nada. Esta es la cadena de conexión correcta.

En Codespaces o Contenedores de desarrollo, la cadena de conexión es incorrecta. ¡Si usa Codespace o Dev Container, debe cambiar la cadena de conexión de la siguiente manera! Asegúrese de guardar los cambios.

"ConnectionStrings": {
    "RazorPagesPizzaAuthConnection": "Data Source=localhost;Initial Catalog=RazorPagesPizza;Integrated Security=False;User Id=sa;Password=P@ssw0rd;MultipleActiveResultSets=True;Encrypt=False"
}

Esto actualiza la cadena de conexión para conectarse a la instancia de SQL Server dentro del contenedor.

Actualizar la base de datos

Ahora que ha comprobado la cadena de conexión, puede generar y ejecutar una migración para compilar la base de datos.

  1. Ejecute el siguiente comando para compilar la aplicación:

    dotnet build
    

    La compilación se ejecuta correctamente sin advertencias. Si se produce un error en la compilación, compruebe el resultado con el fin de obtener información para solucionar problemas.

  2. Instale la herramienta de migración de Entity Framework Core:

    dotnet tool install dotnet-ef --version 8.0.* --global
    

    La herramienta de migración es una herramienta de .NET que:

    • Genera código denominado migración para crear y actualizar la base de datos que admite el modelo de entidad de Identity.
    • Ejecuta migraciones en una base de datos existente.
    • Se invoca a través de dotnet ef en este módulo.
  3. Para actualizar la base de datos, cree y ejecute una migración de EF Core:

    dotnet ef migrations add CreateIdentitySchema
    dotnet ef database update
    

    La migración de EF Core CreateIdentitySchema ha aplicado un script de cambios del lenguaje de definición de datos (DDL) para crear las tablas que son compatibles con Identity. Por ejemplo, en la salida siguiente se muestra una instrucción CREATE TABLE generada por la migración:

    info: Microsoft.EntityFrameworkCore.Database.Command[20101]
          Executed DbCommand (98ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
          CREATE TABLE [AspNetUsers] (
              [Id] nvarchar(450) NOT NULL,
              [UserName] nvarchar(256) NULL,
              [NormalizedUserName] nvarchar(256) NULL,
              [Email] nvarchar(256) NULL,
              [NormalizedEmail] nvarchar(256) NULL,
              [EmailConfirmed] bit NOT NULL,
              [PasswordHash] nvarchar(max) NULL,
              [SecurityStamp] nvarchar(max) NULL,
              [ConcurrencyStamp] nvarchar(max) NULL,
              [PhoneNumber] nvarchar(max) NULL,
              [PhoneNumberConfirmed] bit NOT NULL,
              [TwoFactorEnabled] bit NOT NULL,
              [LockoutEnd] datetimeoffset NULL,
              [LockoutEnabled] bit NOT NULL,
              [AccessFailedCount] int NOT NULL,
              CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id])
          );
    

    Sugerencia

    ¿Produjo el ef comando un error sobre LocalDb que no se admite? Asegúrese de haber establecido la cadena de conexión, como se describe en la sección "Configuración de la conexión de base de datos".

  4. La extensión SQL Server se ha agregado a Visual Studio Code, si era necesario, cuando ha aceptado las extensiones recomendadas. Presione Ctrl+Alt+D para cambiar al panel SQL Server.

  5. Expanda los nodos en la conexión de base de datos existente. Expanda el nodo Bases de datos, después RazorPagesPizza y, por último, el nodo Tablas. Observe la lista de tablas. Esto confirma que la migración se ha realizado correctamente.

    La base de datos RazorPagesPizza con las tablas recientemente creadas.

    Nota

    En la imagen anterior se muestra un ejemplo con LocalDB de SQL Server Express. Al usar .devcontainer, la conexión se denomina mssql-container.

Vuelva al panel Explorador. En Pages/Shared/_Layout.cshtml, reemplace el comentario @* Add the _LoginPartial partial view *@ por lo siguiente.

<partial name="_LoginPartial" />

El marcado anterior representa la vista parcial _LoginPartial en el encabezado de cualquier página que use el diseño predeterminado. El scaffolding de identidad ha agregado _LoginPartial. En esta vista parcial se muestran al usuario los vínculos Iniciar sesión y Registrarse, en caso de que el usuario no haya iniciado sesión.

Prueba de la funcionalidad de Identity

Eso es todo lo necesario para agregar la implementación de Identity predeterminada. Es hora de probarla.

  1. Asegúrese de guardar todos los cambios.

  2. En el panel de terminal, compile el proyecto y ejecute la aplicación:

    dotnet run
    
  3. Vaya a la aplicación en el explorador como antes.

  4. Seleccione el vínculo Registrarse en el encabezado de la aplicación. Rellene el formulario para crear una cuenta nueva.

    Se muestra la página de confirmación del registro. Como la aplicación no se ha configurado para enviar correos electrónicos de confirmación, el vínculo de confirmación se proporciona en esta página.

  5. Seleccione el vínculo de confirmación. Se muestra un mensaje de confirmación.

  6. Seleccione el vínculo Inicio de sesión en el encabezado de la aplicación e inicie sesión.

    Tras un inicio de sesión correcto:

    • Se le redirigirá a la página principal.
    • El encabezado de la aplicación muestra Hola [dirección de correo electrónico] y un vínculo Cerrar sesión.
    • Se crea una cookie llamada .AspNetCore.Identity.Application. Identity conserva las sesiones de usuario con autenticación basada en cookies.
  7. Seleccione el vínculo Cerrar sesión en el encabezado de la aplicación.

    Después de haber cerrado la sesión correctamente, se elimina la cookie .AspNetCore.Identity.Application para finalizar la sesión de usuario.

  8. Para detener la aplicación, presione Ctrl+C en el panel del terminal.

Resumen

En esta unidad, ha agregado la implementación de Identity predeterminada a una aplicación web existente. En la unidad siguiente, obtendrá información sobre cómo extender y personalizar Identity.