Eventos
Campeonato mundial de DataViz de Power BI
14 feb, 16 - 31 mar, 16
Con 4 posibilidades de entrar, podrías ganar un paquete de conferencia y convertirlo en el Live Grand Finale en Las Vegas
Saber másEste explorador ya no se admite.
Actualice a Microsoft Edge para aprovechar las características y actualizaciones de seguridad más recientes, y disponer de soporte técnico.
Por Rick Anderson
Identity de ASP.NET Core:
Los usuarios pueden crear una cuenta con la información de inicio de sesión almacenada en Identity o pueden usar un proveedor de inicio de sesión externo. Entre los proveedores de inicio de sesión externos admitidos se incluyen Facebook, Google, Cuenta Microsoft y Twitter.
Para obtener información sobre cómo requerir globalmente la autenticación de todos los usuarios, consulta Requerir usuarios autenticados.
El código fuente de Identity está disponible en GitHub. Haz scaffolding Identity y mira los archivos generados para revisar la interacción de la plantilla con Identity.
Identity suele configurarse usando una base de datos de SQL Server para almacenar nombres de usuario, contraseñas y datos de perfil. Como alternativa, se puede usar otro almacén persistente, por ejemplo, Azure Table Storage.
En este tema, obtendrás información sobre cómo usar Identity para registrar un usuario e iniciar o cerrar su sesión. Nota: las plantillas tratan el nombre de usuario y el correo electrónico como los mismos para los usuarios. Para obtener instrucciones más detalladas sobre cómo crear aplicaciones que usan Identity, consulta Pasos siguientes.
ASP.NET Core Identity no está relacionado con la plataforma de identidad de Microsoft . La plataforma de identidad de Microsoft es:
ASP.NET Core Identity agrega la funcionalidad de inicio de sesión de la interfaz de usuario (IU) a las aplicaciones web de ASP.NET Core. Para proteger las API web y las SPA, usa una de las siguientes opciones:
Duende Identity Server es un marco de OpenID Connect y OAuth 2.0 para ASP.NET Core. Duende Identity Server permite las siguientes características de seguridad:
Importante
Duende Software puede requerir que pagues una tarifa de licencia para el uso en producción de Duende Identity Server. Para obtener más información, consulta Migración de ASP.NET Core 5.0 a 6.0.
Para obtener más información, consulta la documentación de Duende Identity Server (sitio web de Duende Software).
Mira o descarga el código de ejemplo (cómo descargarlo).
Crea un proyecto de aplicación web de ASP.NET Core con cuentas de usuario individuales.
El proyecto generado proporciona ASP.NET Core Identity como una biblioteca de clases de Razor. La biblioteca de clases de IdentityRazor expone puntos de conexión con el área Identity
. Por ejemplo:
Aplica las migraciones para inicializar la base de datos.
Ejecuta el siguiente comando en la consola del administrador de paquetes (PMC):
Update-Database
Ejecuta la aplicación y registra un usuario. En función del tamaño de la pantalla, es posible que tengas que seleccionar el botón de alternancia de navegación para ver los vínculos Registrar e Iniciar sesión .
Los servicios se agregan en Program.cs
. El patrón típico es llamar a métodos en el orden siguiente:
Add{Service}
builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
builder.Services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
El código anterior configura Identity con los valores predeterminados de las opciones. Los servicios se ponen a disposición de la aplicación mediante inyección de dependencias.
Identity se habilita llamando a UseAuthentication. UseAuthentication
agrega la autenticación de middleware a la canalización de solicitudes.
La aplicación generada por la plantilla no usa la autorización. app.UseAuthorization
se incluye para asegurar que se agrega en el orden correcto en caso de que la aplicación agregue la autorización. Se debe llamar a UseRouting
, UseAuthentication
y UseAuthorization
en el orden mostrado en el código anterior.
Para obtener más información sobre IdentityOptions
, consulta IdentityOptions e Inicio de la aplicación.
Agrega los archivos Register
, Login
, LogOut
y RegisterConfirmation
. Siga las instrucciones de Identidad de scaffolding en un proyecto de Razor con autorización para generar el código que se muestra en esta sección.
Cuando un usuario hace clic en el botón Registrar de la página Register
, se invoca la acción RegisterModel.OnPostAsync
. El usuario es creado por CreateAsync(TUser) en el objeto _userManager
:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
.ToList();
if (ModelState.IsValid)
{
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation",
new { email = Input.Email });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Con las plantillas predeterminadas, se redirige al usuario al Account.RegisterConfirmation
donde puede seleccionar un vínculo para que se confirme la cuenta. El Account.RegisterConfirmation
predeterminado se usa solo para pruebas, la verificación automática de cuentas debería estar desactivada en una aplicación de producción.
Para requerir una cuenta confirmada e impedir el inicio de sesión inmediato en el registro, establezca DisplayConfirmAccountLink = false
en /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
public string Email { get; set; }
public bool DisplayConfirmAccountLink { get; set; }
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
El formulario de inicio de sesión aparece cuando:
Cuando se envía el formulario en la página Inicio de sesión, se llama a la acción OnPostAsync
. Se llama a PasswordSignInAsync
en el objeto _signInManager
.
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout,
// set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email,
Input.Password, Input.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new
{
ReturnUrl = returnUrl,
RememberMe = Input.RememberMe
});
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Para obtener información sobre cómo tomar decisiones de autorización, consulte Introducción a la autorización en ASP.NET Core.
El vínculo Cerrar sesión invoca la acción LogoutModel.OnPost
.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace WebApp1.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LogoutModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public void OnGet()
{
}
public async Task<IActionResult> OnPost(string returnUrl = null)
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
if (returnUrl != null)
{
return LocalRedirect(returnUrl);
}
else
{
return RedirectToPage();
}
}
}
}
En el código anterior, el código return RedirectToPage();
debe ser una redirección para que el explorador realice una nueva solicitud y la identidad del usuario se actualice.
SignOutAsync borra las notificaciones del usuario almacenadas en cookie.
La publicación se especifica en Pages/Shared/_LoginPartial.cshtml
:
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index"
title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout"
asp-route-returnUrl="@Url.Page("/", new { area = "" })"
method="post" >
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
</ul>
Las plantillas de proyecto web predeterminadas permiten el acceso anónimo a las páginas principales. Para probar Identity, agregue [Authorize]
:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace WebApp1.Pages
{
[Authorize]
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Si ha iniciado sesión, cierre la sesión. Ejecute la aplicación y seleccione el vínculo Privacy. Se le redirige a la página de inicio de sesión.
Para explorar Identity con más detalle:
Todos los paquetes NuGet dependientes de Identity se incluyen en el marco compartido de ASP.NET Core.
El paquete principal para Identity es Microsoft.AspNetCore.Identity. Este paquete contiene el conjunto básico de interfaces para ASP.NET Core Identity, y está incluido por Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Para más información e instrucciones sobre cómo migrar el almacén existente Identity, consulte Migración de la autenticación y Identity.
Consulte Configuración para obtener un ejemplo que establece los requisitos mínimos de contraseña.
AddDefaultIdentity se introdujo en ASP.NET Core 2.1. Llamar a AddDefaultIdentity
es similar a llamar a lo siguiente:
Para obtener más información, consulta origen AddDefaultIdentity.
Para evitar la publicación de recursos estáticos Identity (hojas de estilos y archivos de JavaScript para la interfaz de usuario de Identity) en la raíz web, agregue la siguiente propiedad ResolveStaticWebAssetsInputsDependsOn
y el destino RemoveIdentityAssets
al archivo de proyecto de la aplicación:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Por Rick Anderson
Identity de ASP.NET Core:
Los usuarios pueden crear una cuenta con la información de inicio de sesión almacenada en Identity o pueden usar un proveedor de inicio de sesión externo. Entre los proveedores de inicio de sesión externos admitidos se incluyen Facebook, Google, Cuenta Microsoft y Twitter.
Para obtener información sobre cómo requerir globalmente la autenticación de todos los usuarios, consulta Requerir usuarios autenticados.
El código fuente de Identity está disponible en GitHub. Haz scaffolding Identity y mira los archivos generados para revisar la interacción de la plantilla con Identity.
Identity suele configurarse usando una base de datos de SQL Server para almacenar nombres de usuario, contraseñas y datos de perfil. Como alternativa, se puede usar otro almacén persistente, por ejemplo, Azure Table Storage.
En este tema, obtendrás información sobre cómo usar Identity para registrar un usuario e iniciar o cerrar su sesión. Nota: las plantillas tratan el nombre de usuario y el correo electrónico como los mismos para los usuarios. Para obtener instrucciones más detalladas sobre cómo crear aplicaciones que usan Identity, consulta Pasos siguientes.
La plataforma de identidad de Microsoft es:
ASP.NET Core Identity agrega la funcionalidad de inicio de sesión de la interfaz de usuario (IU) a las aplicaciones web de ASP.NET Core. Para proteger las API web y las SPA, usa una de las siguientes opciones:
Duende IdentityServer es un marco de OpenID Connect y OAuth 2.0 para ASP.NET Core. Duende IdentityServer habilita las siguientes características de seguridad:
Para más información, consulta Información general de Duende IdentityServer.
Para más información sobre otros proveedores de autenticación, consulte Opciones de autenticación de OSS de la comunidad para ASP.NET Core.
Mira o descarga el código de ejemplo (cómo descargarlo).
Crea un proyecto de aplicación web de ASP.NET Core con cuentas de usuario individuales.
El proyecto generado proporciona ASP.NET Core Identity como una biblioteca de clases de Razor. La biblioteca de clases de IdentityRazor expone puntos de conexión con el área Identity
. Por ejemplo:
Aplica las migraciones para inicializar la base de datos.
Ejecuta el siguiente comando en la consola del administrador de paquetes (PMC):
PM> Update-Database
Ejecuta la aplicación y registra un usuario. En función del tamaño de la pantalla, es posible que tengas que seleccionar el botón de alternancia de navegación para ver los vínculos Registrar e Iniciar sesión .
Los servicios se agregan en ConfigureServices
. El patrón habitual consiste en llamar a todos los métodos Add{Service}
y, luego, a todos los métodos services.Configure{Service}
.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlite(
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
}
El código resaltado anterior configura Identity con los valores predeterminados de las opciones. Los servicios se ponen a disposición de la aplicación mediante inyección de dependencias.
Identity se habilita llamando a UseAuthentication. UseAuthentication
agrega la autenticación de middleware a la canalización de solicitudes.
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();
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlite(
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddRazorPages();
services.Configure<IdentityOptions>(options =>
{
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
// Lockout settings.
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
// User settings.
options.User.AllowedUserNameCharacters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options =>
{
// Cookie settings
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/Identity/Account/Login";
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.SlidingExpiration = true;
});
}
El código anterior configura Identity con los valores predeterminados de las opciones. Los servicios se ponen a disposición de la aplicación mediante inyección de dependencias.
Identity se habilita llamando a UseAuthentication. UseAuthentication
agrega la autenticación de middleware a la canalización de solicitudes.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
La aplicación generada por la plantilla no usa la autorización. app.UseAuthorization
se incluye para asegurar que se agrega en el orden correcto en caso de que la aplicación agregue la autorización. Se debe llamar a UseRouting
, UseAuthentication
, UseAuthorization
y UseEndpoints
en el orden mostrado en el código anterior.
Para más información sobre IdentityOptions
y Startup
, consulte IdentityOptions e Inicio de la aplicación.
Agrega los archivos Register
, Login
, LogOut
y RegisterConfirmation
. Siga las instrucciones de Identidad de scaffolding en un proyecto de Razor con autorización para generar el código que se muestra en esta sección.
Cuando un usuario hace clic en el botón Registrar de la página Register
, se invoca la acción RegisterModel.OnPostAsync
. El usuario es creado por CreateAsync(TUser) en el objeto _userManager
:
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
.ToList();
if (ModelState.IsValid)
{
var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = user.Id, code = code },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation",
new { email = Input.Email });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Con las plantillas predeterminadas, se redirige al usuario al Account.RegisterConfirmation
donde puede seleccionar un vínculo para que se confirme la cuenta. El Account.RegisterConfirmation
predeterminado se usa solo para pruebas, la verificación automática de cuentas debería estar desactivada en una aplicación de producción.
Para requerir una cuenta confirmada e impedir el inicio de sesión inmediato en el registro, establezca DisplayConfirmAccountLink = false
en /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
public string Email { get; set; }
public bool DisplayConfirmAccountLink { get; set; }
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
El formulario de inicio de sesión aparece cuando:
Cuando se envía el formulario en la página Inicio de sesión, se llama a la acción OnPostAsync
. Se llama a PasswordSignInAsync
en el objeto _signInManager
.
public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
returnUrl = returnUrl ?? Url.Content("~/");
if (ModelState.IsValid)
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout,
// set lockoutOnFailure: true
var result = await _signInManager.PasswordSignInAsync(Input.Email,
Input.Password, Input.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
_logger.LogInformation("User logged in.");
return LocalRedirect(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToPage("./LoginWith2fa", new
{
ReturnUrl = returnUrl,
RememberMe = Input.RememberMe
});
}
if (result.IsLockedOut)
{
_logger.LogWarning("User account locked out.");
return RedirectToPage("./Lockout");
}
else
{
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return Page();
}
}
// If we got this far, something failed, redisplay form
return Page();
}
Para obtener información sobre cómo tomar decisiones de autorización, consulte Introducción a la autorización en ASP.NET Core.
El vínculo Cerrar sesión invoca la acción LogoutModel.OnPost
.
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace WebApp1.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class LogoutModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;
}
public void OnGet()
{
}
public async Task<IActionResult> OnPost(string returnUrl = null)
{
await _signInManager.SignOutAsync();
_logger.LogInformation("User logged out.");
if (returnUrl != null)
{
return LocalRedirect(returnUrl);
}
else
{
return RedirectToPage();
}
}
}
}
En el código anterior, el código return RedirectToPage();
debe ser una redirección para que el explorador realice una nueva solicitud y la identidad del usuario se actualice.
SignOutAsync borra las notificaciones del usuario almacenadas en cookie.
La publicación se especifica en Pages/Shared/_LoginPartial.cshtml
:
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index"
title="Manage">Hello @User.Identity.Name!</a>
</li>
<li class="nav-item">
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout"
asp-route-returnUrl="@Url.Page("/", new { area = "" })"
method="post" >
<button type="submit" class="nav-link btn btn-link text-dark">Logout</button>
</form>
</li>
}
else
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
</ul>
Las plantillas de proyecto web predeterminadas permiten el acceso anónimo a las páginas principales. Para probar Identity, agregue [Authorize]
:
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace WebApp1.Pages
{
[Authorize]
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
Si ha iniciado sesión, cierre la sesión. Ejecute la aplicación y seleccione el vínculo Privacy. Se le redirige a la página de inicio de sesión.
Para explorar Identity con más detalle:
Todos los paquetes NuGet dependientes de Identity se incluyen en el marco compartido de ASP.NET Core.
El paquete principal para Identity es Microsoft.AspNetCore.Identity. Este paquete contiene el conjunto básico de interfaces para ASP.NET Core Identity, y está incluido por Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Para más información e instrucciones sobre cómo migrar el almacén existente Identity, consulte Migración de la autenticación y Identity.
Consulte Configuración para obtener un ejemplo que establece los requisitos mínimos de contraseña.
Para evitar la publicación de recursos estáticos Identity (hojas de estilos y archivos de JavaScript para la interfaz de usuario de Identity) en la raíz web, agregue la siguiente propiedad ResolveStaticWebAssetsInputsDependsOn
y el destino RemoveIdentityAssets
al archivo de proyecto de la aplicación:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Comentarios de ASP.NET Core
ASP.NET Core es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Eventos
Campeonato mundial de DataViz de Power BI
14 feb, 16 - 31 mar, 16
Con 4 posibilidades de entrar, podrías ganar un paquete de conferencia y convertirlo en el Live Grand Finale en Las Vegas
Saber másCursos
Módulo
Protección de una aplicación web de .NET mediante el marco de Identity de ASP.NET Core - Training
Obtenga información sobre cómo agregar la autenticación y la autorización a una aplicación web de .NET mediante el marco de Identity de ASP.NET Core.
Certificación
Microsoft Certified: Identity and Access Administrator Associate - Certifications
Muestre las características de Microsoft Entra ID para modernizar las soluciones de identidad, implementar soluciones híbridas e implementar la gobernanza de identidades.
Documentación
Uso de Identity para proteger un back-end de API web para SPA
Aprenda a usar Identity para proteger un back-end de API web para aplicaciones de página única (SPA).
Scaffolding de Identity en proyectos de ASP.NET Core
Aprenda a aplicar scaffolding de Identity en un proyecto de ASP.NET Core.
Configuración de ASP.NET Core Identity
Comprenda los valores predeterminados de ASP.NET Core Identity y aprenda a configurar las propiedades de Identity para utilizar valores personalizados.