Scaffolding Identity en ASP.NET Core proyectos
Por Rick Anderson
ASP.NET Core proporciona ASP.NET Core Identity como biblioteca Razor de clases. Las aplicaciones que incluyen pueden aplicar la carpeta scaffolder para agregar selectivamente el código fuente Identity contenido en la biblioteca de clases Identity Razor (RCL). Puede que quiera generar código fuente que le permita modificar un código y cambiar el comportamiento; así, por ejemplo, podría indicar al proveedor de scaffolding que generara el código que se usa en el registro. El código generado tiene prioridad sobre el mismo código de la RCL de Identity. Para obtener el control total de la interfaz de usuario y no usar la RCL predeterminada, consulte la sección Creación de un origen de interfaz Identity de usuario completo.
Las aplicaciones que no incluyen la autenticación pueden aplicar la carpeta scaffolder para agregar el paquete de Identity RCL. Tiene la opción de seleccionar el código de Identity que se va a generar.
Aunque la carpeta scaffolder genera la mayor parte del código necesario, debe actualizar el proyecto para completar el proceso. En este documento se explican los pasos necesarios para completar una Identity actualización de scaffolding.
Se recomienda usar un sistema de control de código fuente que muestre las diferencias de archivos y le permita realizar cambios. Inspeccione los cambios después de ejecutar Identity la carpeta scaffolder.
Los servicios son necesarios cuando se usa Two Factor Authentication,confirmación de cuenta y recuperación de contraseña,y otras características de seguridad con Identity . Los servicios o códigos auxiliares de servicio no se generan al scaffolding. Identity Los servicios para habilitar estas características deben agregarse manualmente. Por ejemplo, vea Requerir confirmación por correo electrónico.
Al scaffolding Identity con un nuevo contexto de datos en un proyecto con cuentas individuales existentes:
- En
Startup.ConfigureServices, quite las llamadas a:AddDbContextAddDefaultIdentity
Por ejemplo, AddDbContext y AddDefaultIdentity se comentan en el código siguiente:
public void ConfigureServices(IServiceCollection services)
{
//services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlServer(
// Configuration.GetConnectionString("DefaultConnection")));
//services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
// .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
}
El código anterior comenta el código duplicado en Areas/ Identity / Identity HostingStartup.cs
Normalmente, las aplicaciones que se crearon con cuentas individuales no deben crear un contexto de datos nuevo.
Aplicación de scaffolding Identity en un proyecto vacío
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Actualice la Startup clase con código similar al siguiente:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Aplicación de scaffolding Identity a un proyecto sin autorización Razor existente
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Identityse configura en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Migraciones, UseAuthentication y diseño
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Enable authentication (Habilitar autenticación)
Actualice la Startup clase con código similar al siguiente:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
Cambios de diseño
Opcional: agregue el inicio de sesión parcial ( _LoginPartial ) al archivo de diseño:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebRP</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<partial name="_LoginPartial" />
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
Scaffolding Identity en un proyecto con Razor autorización
Ejecute la Identity carpeta scaffolder:
- En Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Páginas o proyectos con infraestructura de Pages Blazor Server Razor existente~/Views/Shared/_Layout.cshtmlpara proyectos de MVC Blazor Server o proyectos con infraestructura MVC existente
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Algunas Identity opciones se configuran en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Aplicación de scaffolding Identity a un proyecto MVC sin autorización existente
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Opcional: agregue el inicio de sesión parcial ( _LoginPartial ) al archivo Views/Shared/_Layout.cshtml:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebRP</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<partial name="_LoginPartial" />
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
- Mueva el archivo Pages/Shared/_LoginPartial.cshtml a Views/Shared/_LoginPartial.cshtml
Identityse configura en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Actualice la Startup clase con código similar al siguiente:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
Aplicación de scaffolding Identity a un proyecto MVC con autorización
Ejecute la Identity carpeta scaffolder:
- En Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Páginas o proyectos con infraestructura de Pages Blazor Server Razor existente~/Views/Shared/_Layout.cshtmlpara proyectos de MVC Blazor Server o proyectos con infraestructura MVC existente
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Aplicación de scaffolding Identity a un proyecto sin autorización Blazor Server existente
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Identityse configura en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Migraciones
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Pasar un token XSRF a la aplicación
Los tokens se pueden pasar a los componentes:
- Cuando los tokens de autenticación se aprovisionan y se guardan en la cookie autenticación, se pueden pasar a los componentes.
- Razor Los componentes no pueden usar directamente, por lo que no hay ninguna manera de obtener un token de falsificación de solicitud
HttpContext(XSRF) para POST en el punto de conexión de cierre de sesión Identity en/Identity/Account/Logout. Un token XSRF se puede pasar a los componentes.
Para más información, consulte Otros escenarios de seguridad de Blazor Server en ASP.NET Core.
En el archivo Pages/_Host.cshtml, establezca el token después de agregarlo a las InitialApplicationState clases y TokenProvider :
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
...
var tokens = new InitialApplicationState
{
...
XsrfToken = Xsrf.GetAndStoreTokens(HttpContext).RequestToken
};
Actualice el App componente (App.razor) para asignar InitialState.XsrfToken :
@inject TokenProvider TokenProvider
...
TokenProvider.XsrfToken = InitialState.XsrfToken;
El servicio que se muestra en el tema se usa en el componente de la siguiente sección Cambios de flujo de diseño TokenProvider LoginDisplay y autenticación.
Enable authentication (Habilitar autenticación)
En la clase Startup:
- Confirme que Razor los servicios de Pages se han agregado en
Startup.ConfigureServices. - Si usa TokenProvider,registre el servicio.
- Llame
UseDatabaseErrorPagea en el generador de aplicaciones en para el entorno deStartup.Configuredesarrollo. - Llame
UseAuthenticationa y después deUseAuthorizationUseRouting. - Agregue un punto de conexión para Razor Pages.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddScoped<TokenProvider>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
Cambios en el diseño y el flujo de autenticación
Agregue un RedirectToLogin componente (RedirectToLogin.razor) a la carpeta Shared de la aplicación en la raíz del proyecto:
@inject NavigationManager Navigation
@code {
protected override void OnInitialized()
{
Navigation.NavigateTo("Identity/Account/Login?returnUrl=" +
Uri.EscapeDataString(Navigation.Uri), true);
}
}
Agregue un LoginDisplay componente (LoginDisplay.razor) a la carpeta Shared de la aplicación. El servicio TokenProvider proporciona el token XSRF para el formulario HTML que posta al punto de conexión de cierre de Identity sesión:
@using Microsoft.AspNetCore.Components.Authorization
@inject NavigationManager Navigation
@inject TokenProvider TokenProvider
<AuthorizeView>
<Authorized>
<a href="Identity/Account/Manage/Index">
Hello, @context.User.Identity.Name!
</a>
<form action="/Identity/Account/Logout?returnUrl=%2F" method="post">
<button class="nav-link btn btn-link" type="submit">Logout</button>
<input name="__RequestVerificationToken" type="hidden"
value="@TokenProvider.XsrfToken">
</form>
</Authorized>
<NotAuthorized>
<a href="Identity/Account/Register">Register</a>
<a href="Identity/Account/Login">Login</a>
</NotAuthorized>
</AuthorizeView>
En el MainLayout componente (Shared/MainLayout.razor), agregue el componente al contenido del elemento de LoginDisplay fila <div> superior:
<div class="top-row px-4 auth">
<LoginDisplay />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
Puntos de conexión de autenticación de estilo
Dado que usa páginas pages, el estilo de la interfaz de usuario cambia cuando un visitante Blazor Server navega entre páginas y Razor Identity Identity componentes. Tiene dos opciones para abordar los estilos incongruentes:
Componentes de Identity compilación
Un enfoque para usar componentes para Identity en lugar de páginas es compilar Identity componentes. Dado SignInManager que y no se UserManager admiten en los componentes, use puntos de conexión de API en la aplicación para procesar Razor las acciones de la cuenta de Blazor Server usuario.
Uso de un diseño personalizado con estilos Blazor de aplicación
El Identity diseño y los estilos de las páginas se pueden modificar para generar páginas que usen el tema Blazor predeterminado.
Nota
El ejemplo de esta sección es simplemente un punto de partida para la personalización. Es probable que se requiera trabajo adicional para la mejor experiencia del usuario.
Cree un nuevo NavMenu_IdentityLayout componente (Shared/NavMenu_ Identity Layout.razor). Para el marcado y el código del componente, use el mismo contenido del componente de la aplicación NavMenu (Shared/NavMenu.razor). Elimina los componentes a los que no se puede acceder de forma anónima porque se producirá un error en los redireccionamientos automáticos del componente para los componentes que NavLink RedirectToLogin requieren autenticación o autorización.
En el archivo Pages/Shared/Layout.cshtml, realice los cambios siguientes:
Agregue directivas a la parte superior del archivo para usar los asistentes de etiquetas y los componentes de la Razor aplicación en la carpeta Compartido:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @using {APPLICATION ASSEMBLY}.SharedReemplace
{APPLICATION ASSEMBLY}por el nombre del ensamblado de la aplicación.Agregue una
<base>etiqueta y una hoja de estilos al Blazor<link><head>contenido:<base href="~/" /> <link rel="stylesheet" href="~/css/site.css" />Cambie el contenido de
<body>la etiqueta a lo siguiente:<div class="sidebar" style="float:left"> <component type="typeof(NavMenu_IdentityLayout)" render-mode="ServerPrerendered" /> </div> <div class="main" style="padding-left:250px"> <div class="top-row px-4"> @{ var result = Engine.FindView(ViewContext, "_LoginPartial", isMainPage: false); } @if (result.Success) { await Html.RenderPartialAsync("_LoginPartial"); } else { throw new InvalidOperationException("The default Identity UI " + "layout requires a partial view '_LoginPartial'."); } <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a> </div> <div class="content px-4"> @RenderBody() </div> </div> <script src="~/Identity/lib/jquery/dist/jquery.min.js"></script> <script src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/Identity/js/site.js" asp-append-version="true"></script> @RenderSection("Scripts", required: false) <script src="_framework/blazor.server.js"></script>
Scaffolding Identity en un proyecto con Blazor Server autorización
Ejecute la Identity carpeta scaffolder:
- En Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Páginas o proyectos con infraestructura de Pages Blazor Server Razor existente~/Views/Shared/_Layout.cshtmlpara proyectos de MVC Blazor Server o proyectos con infraestructura MVC existente
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Algunas Identity opciones se configuran en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Aplicaciones independientes u Blazor WebAssembly hospedadas
Las aplicaciones del Blazor WebAssembly lado cliente usan sus propios Identity enfoques de interfaz de usuario y no pueden usar ASP.NET Core Identity scaffolding. Las aplicaciones de ASP.NET Core del lado servidor de soluciones hospedadas pueden seguir las instrucciones de Blazor Pages/MVC de este artículo y se configuran como cualquier otro tipo de aplicación ASP.NET Core que admita Razor Identity .
El Blazor marco de trabajo no incluye versiones de componentes de páginas de interfaz de Razor Identity usuario. Identity Los componentes de la interfaz de usuario se pueden crear Razor u obtener personalizados de orígenes de terceros no admitidos.
Para obtener más información, vea los Blazor artículos Seguridad Identity y.
Creación de un origen de Identity interfaz de usuario completo
Para mantener el control total de la interfaz Identity de usuario, ejecute Identity la carpeta scaffolder y seleccione Invalidar todos los archivos.
El código resaltado siguiente muestra los cambios para reemplazar la interfaz de usuario Identity predeterminada por en una aplicación web ASP.NET Core Identity 2.1. Es posible que quiera hacerlo para tener control total de la interfaz de Identity usuario.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>()
// services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
}
El valor Identity predeterminado se reemplaza en el código siguiente:
services.AddIdentity<IdentityUser, IdentityRole>()
// services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
El código siguiente establece LoginPath, LogoutPathy AccessDeniedPath:
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
Registre una IEmailSender implementación, por ejemplo:
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
public class EmailSender : IEmailSender
{
public Task SendEmailAsync(string email, string subject, string message)
{
return Task.CompletedTask;
}
}
Configuración de contraseñas
Si están configurados en , puede ser necesaria la configuración de atributos PasswordOptions para la propiedad en páginas con Startup.ConfigureServices [StringLength] Password Identity scaffolding. InputModel``PasswordLas propiedades se encuentran en los archivos siguientes:
Areas/Identity/Pages/Account/Register.cshtml.csAreas/Identity/Pages/Account/ResetPassword.cshtml.cs
Deshabilitar una página
En estas secciones se muestra cómo deshabilitar la página de registro, pero el enfoque se puede usar para deshabilitar cualquier página.
Para deshabilitar el registro de usuarios:
Scaffold Identity . Incluya Account.Register, Account.Login y Account.RegisterConfirmation. Por ejemplo:
dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"Actualice Areas/ Identity /Pages/Account/Register.cshtml.cs para que los usuarios no puedan registrarse desde este punto de conexión:
public class RegisterModel : PageModel { public IActionResult OnGet() { return RedirectToPage("Login"); } public IActionResult OnPost() { return RedirectToPage("Login"); } }Actualice Areas/ Identity /Pages/Account/Register.cshtml para que sean coherentes con los cambios anteriores:
@page @model RegisterModel @{ ViewData["Title"] = "Go to Login"; } <h1>@ViewData["Title"]</h1> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li>Comentar o quitar el vínculo de registro de Areas/ Identity /Pages/Account/Login.cshtml
@* <p> <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a> </p> *@Actualice la página Identity Areas//Pages/Account/RegisterConfirmation.
- Quite el código y los vínculos del archivo cshtml.
- Quite el código de confirmación de
PageModel:
[AllowAnonymous] public class RegisterConfirmationModel : PageModel { public IActionResult OnGet() { return Page(); } }
Uso de otra aplicación para agregar usuarios
Proporcione un mecanismo para agregar usuarios fuera de la aplicación web. Las opciones para agregar usuarios incluyen:
- Una aplicación web de administración dedicada.
- Una aplicación de consola.
En el código siguiente se describe un enfoque para agregar usuarios:
- Se lee una lista de usuarios en la memoria.
- Se genera una contraseña única segura para cada usuario.
- El usuario se agrega a la base de Identity datos.
- Se notifica al usuario y se le notifica que cambie la contraseña.
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<AppDbCntx>();
context.Database.Migrate();
var config = host.Services.GetRequiredService<IConfiguration>();
var userList = config.GetSection("userList").Get<List<string>>();
SeedData.Initialize(services, userList).Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred adding users.");
}
}
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
En el código siguiente se describe cómo agregar un usuario:
public static async Task Initialize(IServiceProvider serviceProvider,
List<string> userList)
{
var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();
foreach (var userName in userList)
{
var userPassword = GenerateSecurePassword();
var userId = await EnsureUser(userManager, userName, userPassword);
NotifyUser(userName, userPassword);
}
}
private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
string userName, string userPassword)
{
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
user = new IdentityUser(userName)
{
EmailConfirmed = true
};
await userManager.CreateAsync(user, userPassword);
}
return user.Id;
}
Se puede seguir un enfoque similar para escenarios de producción.
Impedir la publicación de recursos Identity estáticos
Para evitar la publicación de Identity recursos estáticos en la raíz web, vea Introducción a Identity en ASP.NET Core .
Recursos adicionales
ASP.NET Core 2.1 y versiones posteriores proporciona ASP.NET Core Identity como biblioteca Razor de clases. Las aplicaciones que incluyen pueden aplicar la carpeta scaffolder para agregar de forma selectiva el código Identity fuente contenido en la biblioteca de clases Identity Razor (RCL). Puede que quiera generar código fuente que le permita modificar un código y cambiar el comportamiento; así, por ejemplo, podría indicar al proveedor de scaffolding que generara el código que se usa en el registro. El código generado tiene prioridad sobre el mismo código de la RCL de Identity. Para obtener el control total de la interfaz de usuario y no usar la RCL predeterminada, consulte la sección Creación de un origen de interfaz de usuario de identidad completa.
Las aplicaciones que no incluyen la autenticación pueden aplicar la carpeta scaffolder para agregar el paquete de Identity RCL. Tiene la opción de seleccionar el código de Identity que se va a generar.
Aunque la carpeta scaffolder genera la mayor parte del código necesario, tendrá que actualizar el proyecto para completar el proceso. En este documento se explican los pasos necesarios para completar una Identity actualización de scaffolding.
Cuando se Identity ejecuta la carpeta scaffolder, se creaScaffoldingReadme.txt archivo en el directorio del proyecto. El ScaffoldingReadme.txt archivo contiene instrucciones generales sobre lo que se necesita para completar la actualización Identity de scaffolding. Este documento contiene instrucciones más completas que el ScaffoldingReadme.txt archivo.
Se recomienda usar un sistema de control de código fuente que muestre las diferencias de archivos y le permita salir de los cambios. Inspeccione los cambios después de ejecutar Identity la carpeta scaffolder.
Nota
Los servicios son necesarios cuando se usa Two Factor Authentication, confirmación de cuenta y recuperación de contraseña,y otras características de seguridad con Identity . Los servicios o los códigos auxiliares de servicio no se generan al scaffolding Identity . Los servicios para habilitar estas características deben agregarse manualmente. Por ejemplo, vea Requerir confirmación por correo electrónico.
Scaffolding Identity en un proyecto vacío
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Agregue las siguientes llamadas resaltadas a la Startup clase :
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Scaffolding Identity en un proyecto sin autorización Razor existente
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Identityse configura en Areas/ Identity / Identity HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Migraciones, UseAuthentication y diseño
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Enable authentication (Habilitar autenticación)
En el Configure método de la clase , llame a después de Startup UseAuthentication UseStaticFiles :
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
Cambios de diseño
Opcional: agregue el inicio de sesión parcial ( _LoginPartial ) al archivo de diseño:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - RazorNoAuth8</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-page="/Index" class="navbar-brand">RazorNoAuth8</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-page="/Index">Home</a></li>
<li><a asp-page="/About">About</a></li>
<li><a asp-page="/Contact">Contact</a></li>
</ul>
<partial name="_LoginPartial" />
</div>
</div>
</nav>
<partial name="_CookieConsentPartial" />
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2018 - RazorNoAuth8</p>
</footer>
</div>
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
</body>
</html>
Scaffolding Identity en un proyecto con Razor autorización
Ejecute la Identity carpeta scaffolder:
- En Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Páginas o proyectos con infraestructura de Pages Blazor Server Razor existente~/Views/Shared/_Layout.cshtmlpara proyectos de MVC Blazor Server o proyectos con infraestructura MVC existente
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Algunas Identity opciones se configuran en Identity / Identity Areas/HostingStartup.cs. Para obtener más información, vea IHostingStartup.
Scaffolding Identity en un proyecto MVC sin autorización existente
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar nuevo elemento con scaffolding, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc- Blazor Server Las aplicaciones creadas Blazor Server a partir de la plantilla ( ) no están
blazorserverconfiguradas para Pages o MVC de Razor forma predeterminada. Deje la entrada de la página de diseño en blanco.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext).
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto:
- Seleccione Agregar.
Opcional: agregue el inicio de sesión parcial ( _LoginPartial ) al archivo Views/Shared/_Layout.cshtml:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MvcNoAuth3</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MvcNoAuth3</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
<partial name="_LoginPartial" />
</div>
</div>
</nav>
<partial name="_CookieConsentPartial" />
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2018 - MvcNoAuth3</p>
</footer>
</div>
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
</body>
</html>
- Mover el archivo Pages/Shared/_LoginPartial.cshtml a Views/Shared/_LoginPartial.cshtml
Identityse configura en Areas/ Identity / Identity HostingStartup.cs. Para obtener más información, vea IHostingStartup.
El código de Identity base de datos generado requiere Entity Framework Core migrations. Cree una migración y actualice la base de datos. Por ejemplo, ejecute los siguientes comandos:
En la consola Visual Studio Administrador de paquetes :
Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database
El parámetro de Identity nombre "Crear esquema" para Add-Migration el comando es arbitrario. "CreateIdentitySchema" describe la migración.
Llame UseAuthentication a después de UseStaticFiles :
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
}
UseHsts se recomienda, pero no es necesario. Para obtener más información, vea Protocolo de seguridad de transporteestricto HTTP .
Scaffolding Identity en un proyecto MVC con autorización
Ejecute la Identity carpeta scaffolder:
- En Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Páginas o proyectos con infraestructura de Pages Blazor Server Razor existente~/Views/Shared/_Layout.cshtmlpara proyectos de MVC Blazor Server o proyectos con infraestructura MVC existente
- Seleccione la página de diseño existente para que el archivo de diseño no se sobrescriba con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Ejecute la Identity carpeta scaffolder:
- Desde Explorador de soluciones, haga clic con el botón derecho en el proyecto > Agregar nuevo elemento > con scaffolding.
- En el panel izquierdo del cuadro de diálogo Agregar scaffold, seleccione Identity > Agregar.
- En el cuadro de Identity diálogo Agregar, seleccione las opciones que desee.
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
~/Pages/Shared/_Layout.cshtmlpara Razor Pages~/Views/Shared/_Layout.cshtmlpara proyectos mvc
- Seleccione la página de diseño existente o el archivo de diseño se sobrescribirá con un marcado incorrecto. Cuando se selecciona _ un archivo Layout.cshtml existente, no se sobrescribe. Por ejemplo:
- Para usar el contexto de datos existente, seleccione al menos un archivo para invalidar. Debe seleccionar al menos un archivo para agregar el contexto de datos.
- Seleccione la clase de contexto de datos.
- Seleccione Agregar.
- Para crear un nuevo contexto de usuario y, posiblemente, crear una clase de usuario personalizada para Identity :
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
MyApplication.Data.ApplicationDbContext). - Seleccione Agregar.
- Seleccione el + botón para crear una nueva clase de contexto de datos. Acepte el valor predeterminado o especifique una clase (por ejemplo,
Nota: Si va a crear un nuevo contexto de usuario, no tiene que seleccionar un archivo para invalidarlo.
Elimine la carpeta Pages/Shared y los archivos de esa carpeta.
Creación de un origen de Identity interfaz de usuario completo
Para mantener el control total de la interfaz Identity de usuario, ejecute Identity la carpeta scaffolder y seleccione Invalidar todos los archivos.
El código resaltado siguiente muestra los cambios para reemplazar la interfaz de usuario Identity predeterminada por en una ASP.NET Core web de ASP.NET Core Identity 2.1. Es posible que quiera hacerlo para tener control total de la interfaz de Identity usuario.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<IdentityUser, IdentityRole>()
// services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc()
.AddRazorPagesOptions(options =>
{
options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
});
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
}
El valor Identity predeterminado se reemplaza en el código siguiente:
services.AddIdentity<IdentityUser, IdentityRole>()
// services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
El código siguiente establece LoginPath, LogoutPathy AccessDeniedPath:
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = $"/Identity/Account/Login";
options.LogoutPath = $"/Identity/Account/Logout";
options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});
Registre una IEmailSender implementación, por ejemplo:
// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
public class EmailSender : IEmailSender
{
public Task SendEmailAsync(string email, string subject, string message)
{
return Task.CompletedTask;
}
}
Configuración de contraseñas
Si están configurados en , puede ser necesaria la configuración de atributos PasswordOptions para la propiedad en páginas con Startup.ConfigureServices [StringLength] Password Identity scaffolding. InputModel``PasswordLas propiedades se encuentran en los archivos siguientes:
Areas/Identity/Pages/Account/Register.cshtml.csAreas/Identity/Pages/Account/ResetPassword.cshtml.cs
Deshabilitar la página de registro
Para deshabilitar el registro de usuarios:
Scaffold Identity . Incluya Account.Register, Account.Login y Account.RegisterConfirmation. Por ejemplo:
dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"Actualice Areas/ Identity /Pages/Account/Register.cshtml.cs para que los usuarios no puedan registrarse desde este punto de conexión:
public class RegisterModel : PageModel { public IActionResult OnGet() { return RedirectToPage("Login"); } public IActionResult OnPost() { return RedirectToPage("Login"); } }Actualice Areas/ Identity /Pages/Account/Register.cshtml para que sean coherentes con los cambios anteriores:
@page @model RegisterModel @{ ViewData["Title"] = "Go to Login"; } <h1>@ViewData["Title"]</h1> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li>Comentar o quitar el vínculo de registro de Areas/ Identity /Pages/Account/Login.cshtml
@*
<p>
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
*@
Actualice la página Identity Areas//Pages/Account/RegisterConfirmation.
- Quite el código y los vínculos del archivo cshtml.
- Quite el código de confirmación de
PageModel:
[AllowAnonymous] public class RegisterConfirmationModel : PageModel { public IActionResult OnGet() { return Page(); } }
Uso de otra aplicación para agregar usuarios
Proporcione un mecanismo para agregar usuarios fuera de la aplicación web. Las opciones para agregar usuarios incluyen:
- Una aplicación web de administración dedicada.
- Una aplicación de consola.
En el código siguiente se describe un enfoque para agregar usuarios:
- Se lee una lista de usuarios en la memoria.
- Se genera una contraseña única segura para cada usuario.
- El usuario se agrega a la base de Identity datos.
- Se notifica al usuario y se le notifica que cambie la contraseña.
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
try
{
var context = services.GetRequiredService<AppDbCntx>();
context.Database.Migrate();
var config = host.Services.GetRequiredService<IConfiguration>();
var userList = config.GetSection("userList").Get<List<string>>();
SeedData.Initialize(services, userList).Wait();
}
catch (Exception ex)
{
var logger = services.GetRequiredService<ILogger<Program>>();
logger.LogError(ex, "An error occurred adding users.");
}
}
host.Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
En el código siguiente se describe cómo agregar un usuario:
public static async Task Initialize(IServiceProvider serviceProvider,
List<string> userList)
{
var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();
foreach (var userName in userList)
{
var userPassword = GenerateSecurePassword();
var userId = await EnsureUser(userManager, userName, userPassword);
NotifyUser(userName, userPassword);
}
}
private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
string userName, string userPassword)
{
var user = await userManager.FindByNameAsync(userName);
if (user == null)
{
user = new IdentityUser(userName)
{
EmailConfirmed = true
};
await userManager.CreateAsync(user, userPassword);
}
return user.Id;
}
Se puede seguir un enfoque similar para escenarios de producción.