Úvod do Identity ASP.NET Core
Autor: Rick Anderson
ASP.NET Core Identity:
- Je rozhraní API, které podporuje funkce přihlášení pomocí uživatelského rozhraní.
- Spravuje uživatele, hesla, profilová data, role, deklarace identity, tokeny, potvrzení e-mailu a další.
Uživatelé můžou vytvořit účet s přihlašovacími údaji uloženými v Identity nebo můžou použít externího zprostředkovatele přihlášení. Mezi podporované externí zprostředkovatele přihlášení patří Facebook, Google, Účet Microsoft a Twitter.
Informace o tom, jak globálně vyžadovat ověření všech uživatelů, najdete v tématu Vyžadování ověřených uživatelů.
Identity Zdrojový kód je k dispozici na GitHubu. Generování uživatelského rozhraní Identity a zobrazení vygenerovaných souborů pro kontrolu interakce šablony s Identity.
Identity se obvykle konfiguruje pomocí databáze SQL Serveru k ukládání uživatelských jmen, hesel a dat profilu. Alternativně je možné použít jiné trvalé úložiště, například Azure Table Storage.
V tomto tématu se dozvíte, jak se pomocí Identity registrace, přihlášení a odhlášení uživatele. Poznámka: Šablony považují uživatelské jméno a e-maily za stejné pro uživatele. Podrobnější pokyny k vytváření aplikací, které používají Identity, najdete v tématu Další kroky.
ASP.NET Core Identity nesouvisí s platformou Microsoftu identity . Platforma Microsoftu identity je:
- Vývoj vývojářské platformy Azure Active Directory (Azure AD).
- Alternativní identity řešení pro ověřování a autorizaci v aplikacích ASP.NET Core
ASP.NET Core Identity přidává do webových aplikací ASP.NET Core funkce přihlášení uživatelského rozhraní. K zabezpečení webových rozhraní API a spA použijte jednu z následujících možností:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server je architektura OpenID Connect a OAuth 2.0 pro ASP.NET Core. Duende Identity Server umožňuje následující funkce zabezpečení:
- Ověřování jako služba (AaaS)
- Jednotné přihlašování nebo vypnutí (SSO) u více typů aplikací
- Řízení přístupu pro rozhraní API
- Federační brána
Důležité
Duende Software může vyžadovat, abyste zaplatili licenční poplatek za produkční využití serveru Duende Identity Server. Další informace najdete v tématu Migrace z ASP.NET Core 5.0 na verzi 6.0.
Další informace najdete v dokumentaci k Duende Identity Serveru (web Duende Software).
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Vytvoření webové aplikace s ověřováním
Vytvořte projekt ASP.NET základní webové aplikace s individuálními uživatelskými účty.
- Vyberte šablonu webové aplikace ASP.NET Core. Pojmenujte projekt WebApp1 tak, aby měl stejný obor názvů jako stažení projektu. Klikněte na OK.
- Jako typ ověřování vyberte Individuální uživatelské účty.
Vygenerovaný projekt poskytuje ASP.NET Core Identity jako knihovnu Razortříd. Knihovna IdentityRazor tříd zveřejňuje koncové body s Identity
oblastí. Příklad:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
Použití migrací
Použijte migrace k inicializaci databáze.
V konzole Správce balíčků (PMC) spusťte následující příkaz:
Update-Database
Testování registrace a přihlášení
Spusťte aplikaci a zaregistrujte uživatele. V závislosti na velikosti obrazovky možná budete muset vybrat přepínací tlačítko navigace, aby se zobrazily odkazy Pro registraci a přihlášení .
Identity Zobrazení databáze
- V nabídce Zobrazení vyberte SQL Server Průzkumník objektů (SSOX).
- Přejděte na (localdb)MSSQLLocalDB(SQL Server 13). Klikněte pravým tlačítkem na dbo. AspNetUsers>View Data:
Konfigurace Identity služeb
Služby jsou přidány do Program.cs
. Typickým vzorem je volání metod v následujícím pořadí:
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();
Předchozí kód konfiguruje Identity výchozí hodnoty možností. Služby jsou pro aplikaci zpřístupněny prostřednictvím injektáže závislostí.
Identity je povolen voláním UseAuthentication. UseAuthentication
přidá middleware pro ověřování do kanálu požadavku.
Aplikace generovaná šablonou nepoužívá autorizaci. app.UseAuthorization
je součástí, aby se zajistilo, že je přidaná ve správném pořadí, pokud aplikace přidá autorizaci. UseRouting
, UseAuthentication
a UseAuthorization
musí být volána v pořadí uvedeném v předchozím kódu.
Další informace naleznete v IdentityOptions
tématu IdentityOptions a spuštění aplikace.
Generování uživatelského rozhraní – Registrace, Přihlášení, Odhlášení a RegistraceConfirmace
Přidejte soubor Register
, Login
LogOut
a RegisterConfirmation
soubory. Pokud chcete vygenerovat kód zobrazený v této části, postupujte podle pokynů pro generování uživatelského rozhraní identity do Razor projektu s pokyny pro autorizaci.
Kontrola registru
Když uživatel klikne na tlačítko Zaregistrovat na Register
stránce, RegisterModel.OnPostAsync
vyvolá se akce. Uživatel je vytvořen CreateAsync(TUser) v objektu _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();
}
Zakázání výchozího ověření účtu
U výchozích šablon se uživatel přesměruje na Account.RegisterConfirmation
místo, kde může vybrat odkaz, který má účet potvrzený. Výchozí hodnota Account.RegisterConfirmation
se používá jenom pro testování, automatické ověření účtu by mělo být v produkční aplikaci zakázané.
Pokud chcete vyžadovat potvrzený účet a zabránit okamžitému přihlášení při registraci, nastavte v /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:DisplayConfirmAccountLink = false
[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();
}
}
Přihlášení
Přihlašovací formulář se zobrazí v následujících případech:
- Je vybrán odkaz Přihlásit se.
- Uživatel se pokusí získat přístup k omezené stránce, ke které nemá oprávnění k přístupu nebo když je systém neověřil.
Při odeslání OnPostAsync
formuláře na přihlašovací stránce se volá akce. PasswordSignInAsync
je volána u objektu _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();
}
Informace o tom, jak provádět rozhodnutí o autorizaci, najdete v tématu Úvod k autorizaci v ASP.NET Core.
Odhlásit se
Odkaz Pro odhlášení vyvolá LogoutModel.OnPost
akci.
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();
}
}
}
}
V předchozím kódu musí být kód return RedirectToPage();
přesměrování, aby prohlížeč provedl nový požadavek a identity uživatel se aktualizoval.
SignOutAsync vymaže deklarace identity uživatele uložené v souboru cookie.
Příspěvek je zadán v :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>
Test Identity
Výchozí šablony webového projektu umožňují anonymní přístup ke home stránkám. Chcete-li testovat Identity, přidejte [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()
{
}
}
}
Pokud jste přihlášení, odhlaste se. Spusťte aplikaci a vyberte Privacy odkaz. Budete přesměrováni na přihlašovací stránku.
Prozkoumat Identity
Podrobnější prozkoumání Identity :
- Vytvoření úplného identity zdroje uživatelského rozhraní
- Prozkoumejte zdroj každé stránky a projděte ladicí program.
Identity Součásti
IdentityVšechny balíčky NuGet závislé na nuGetu jsou součástí sdílené architektury ASP.NET Core.
Primárním balíčkem je Identity Microsoft.AspNetCore.Identity. Tento balíček obsahuje základní sadu rozhraní pro ASP.NET Core Identitya je součástí Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migrace na ASP.NET Core Identity
Další informace a pokyny k migraci stávajícího Identity úložiště najdete v tématu Migrace ověřování a Identity.
Nastavení síly hesla
Viz Konfigurace ukázky, která nastavuje minimální požadavky na heslo.
AddDefaultIdentity a AddIdentity
AddDefaultIdentity byla zavedena v ASP.NET Core 2.1. Volání AddDefaultIdentity
se podobá volání následující:
Další informace najdete ve zdroji AddDefaultIdentity.
Zabránění publikování statických Identity prostředků
Pokud chcete zabránit publikování statických Identity prostředků (šablon stylů a souborů JavaScriptu pro Identity uživatelské rozhraní) do kořenového adresáře webu, přidejte do souboru projektu aplikace následující ResolveStaticWebAssetsInputsDependsOn
vlastnost a RemoveIdentityAssets
cíl:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Další kroky
- Informace o konfiguraci Identity pomocí SQLite najdete v tomto problému s GitHubem.
- Konfigurovat Identity
- Vytvoření aplikace ASP.NET Core s uživatelskými daty chráněnými autorizací
- Přidání, stažení a odstranění uživatelských dat do Identity projektu ASP.NET Core
- Povolení generování kódu QR pro ověřovací aplikace TOTP v ASP.NET Core
- Migrace ověřování a Identity ASP.NET Core
- Potvrzení účtu a obnovení hesla v ASP.NET Core
- Dvoufaktorové ověřování pomocí SMS v ASP.NET Core
- Hostování ASP.NET Core ve webové farmě
Autor: Rick Anderson
ASP.NET Core Identity:
- Je rozhraní API, které podporuje funkce přihlášení pomocí uživatelského rozhraní.
- Spravuje uživatele, hesla, profilová data, role, deklarace identity, tokeny, potvrzení e-mailu a další.
Uživatelé můžou vytvořit účet s přihlašovacími údaji uloženými v Identity nebo můžou použít externího zprostředkovatele přihlášení. Mezi podporované externí zprostředkovatele přihlášení patří Facebook, Google, Účet Microsoft a Twitter.
Informace o tom, jak globálně vyžadovat ověření všech uživatelů, najdete v tématu Vyžadování ověřených uživatelů.
Identity Zdrojový kód je k dispozici na GitHubu. Generování uživatelského rozhraní Identity a zobrazení vygenerovaných souborů pro kontrolu interakce šablony s Identity.
Identity se obvykle konfiguruje pomocí databáze SQL Serveru k ukládání uživatelských jmen, hesel a dat profilu. Alternativně je možné použít jiné trvalé úložiště, například Azure Table Storage.
V tomto tématu se dozvíte, jak se pomocí Identity registrace, přihlášení a odhlášení uživatele. Poznámka: Šablony považují uživatelské jméno a e-maily za stejné pro uživatele. Podrobnější pokyny k vytváření aplikací, které používají Identity, najdete v tématu Další kroky.
Platforma Microsoftu identity je:
- Vývoj vývojářské platformy Azure Active Directory (Azure AD).
- Alternativní identity řešení pro ověřování a autorizaci v aplikacích ASP.NET Core
- Nesouvisí s ASP.NET Core Identity.
ASP.NET Core Identity přidává do webových aplikací ASP.NET Core funkce přihlášení uživatelského rozhraní. K zabezpečení webových rozhraní API a spA použijte jednu z následujících možností:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. Duende IdentityServer je produkt třetí strany.
Duende IdentityServer je architektura OpenID Connect a OAuth 2.0 pro ASP.NET Core. Duende IdentityServer umožňuje následující funkce zabezpečení:
- Ověřování jako služba (AaaS)
- Jednotné přihlašování nebo vypnutí (SSO) u více typů aplikací
- Řízení přístupu pro rozhraní API
- Federační brána
Další informace najdete v tématu Přehled duende IdentityServer.
Další informace o jiných poskytovatelích ověřování najdete v tématu Možnosti ověřování OSS komunity pro ASP.NET Core.
Zobrazení nebo stažení ukázkového kódu (postup stažení)
Vytvoření webové aplikace s ověřováním
Vytvořte projekt ASP.NET základní webové aplikace s individuálními uživatelskými účty.
- Vyberte Soubor>Nový>Projekt.
- Vyberte ASP.NET Základní webová aplikace. Pojmenujte projekt WebApp1 tak, aby měl stejný obor názvů jako stažení projektu. Klikněte na OK.
- Vyberte ASP.NET základní webovou aplikaci a pak vyberte Změnit ověřování.
- Vyberte jednotlivé uživatelské účty a klikněte na ok.
Vygenerovaný projekt poskytuje ASP.NET Core Identity jako knihovnu Razortříd. Knihovna IdentityRazor tříd zveřejňuje koncové body s Identity
oblastí. Příklad:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
Použití migrací
Použijte migrace k inicializaci databáze.
V konzole Správce balíčků (PMC) spusťte následující příkaz:
PM> Update-Database
Testování registrace a přihlášení
Spusťte aplikaci a zaregistrujte uživatele. V závislosti na velikosti obrazovky možná budete muset vybrat přepínací tlačítko navigace, aby se zobrazily odkazy Pro registraci a přihlášení .
Identity Zobrazení databáze
- V nabídce Zobrazení vyberte SQL Server Průzkumník objektů (SSOX).
- Přejděte na (localdb)MSSQLLocalDB(SQL Server 13). Klikněte pravým tlačítkem na dbo. AspNetUsers>View Data:
Konfigurace Identity služeb
Služby jsou přidány do ConfigureServices
. Typickým vzorem je volat všechny Add{Service}
metody a pak volat všechny services.Configure{Service}
metody.
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;
});
}
Předchozí zvýrazněný kód konfiguruje Identity výchozí hodnoty možností. Služby jsou pro aplikaci zpřístupněny prostřednictvím injektáže závislostí.
Identity je povolen voláním UseAuthentication. UseAuthentication
přidá middleware pro ověřování do kanálu požadavku.
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;
});
}
Předchozí kód konfiguruje Identity výchozí hodnoty možností. Služby jsou pro aplikaci zpřístupněny prostřednictvím injektáže závislostí.
Identity je povolen voláním UseAuthentication. UseAuthentication
přidá middleware pro ověřování do kanálu požadavku.
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();
});
}
Aplikace generovaná šablonou nepoužívá autorizaci. app.UseAuthorization
je součástí, aby se zajistilo, že je přidaná ve správném pořadí, pokud aplikace přidá autorizaci. UseRouting
, UseAuthentication
, UseAuthorization
a UseEndpoints
musí být volána v pořadí uvedeném v předchozím kódu.
Další informace o IdentityOptions
a Startup
naleznete v tématu IdentityOptions a spuštění aplikace.
Generování uživatelského rozhraní – Registrace, Přihlášení, Odhlášení a RegistraceConfirmace
Přidejte soubor Register
, Login
LogOut
a RegisterConfirmation
soubory. Pokud chcete vygenerovat kód zobrazený v této části, postupujte podle pokynů pro generování uživatelského rozhraní identity do Razor projektu s pokyny pro autorizaci.
Kontrola registru
Když uživatel klikne na tlačítko Zaregistrovat na Register
stránce, RegisterModel.OnPostAsync
vyvolá se akce. Uživatel je vytvořen CreateAsync(TUser) v objektu _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();
}
Zakázání výchozího ověření účtu
U výchozích šablon se uživatel přesměruje na Account.RegisterConfirmation
místo, kde může vybrat odkaz, který má účet potvrzený. Výchozí hodnota Account.RegisterConfirmation
se používá jenom pro testování, automatické ověření účtu by mělo být v produkční aplikaci zakázané.
Pokud chcete vyžadovat potvrzený účet a zabránit okamžitému přihlášení při registraci, nastavte v /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:DisplayConfirmAccountLink = false
[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();
}
}
Přihlášení
Přihlašovací formulář se zobrazí v následujících případech:
- Je vybrán odkaz Přihlásit se.
- Uživatel se pokusí získat přístup k omezené stránce, ke které nemá oprávnění k přístupu nebo když je systém neověřil.
Při odeslání OnPostAsync
formuláře na přihlašovací stránce se volá akce. PasswordSignInAsync
je volána u objektu _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();
}
Informace o tom, jak provádět rozhodnutí o autorizaci, najdete v tématu Úvod k autorizaci v ASP.NET Core.
Odhlásit se
Odkaz Pro odhlášení vyvolá LogoutModel.OnPost
akci.
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();
}
}
}
}
V předchozím kódu musí být kód return RedirectToPage();
přesměrování, aby prohlížeč provedl nový požadavek a identity uživatel se aktualizoval.
SignOutAsync vymaže deklarace identity uživatele uložené v souboru cookie.
Příspěvek je zadán v :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>
Test Identity
Výchozí šablony webového projektu umožňují anonymní přístup ke home stránkám. Chcete-li testovat Identity, přidejte [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()
{
}
}
}
Pokud jste přihlášení, odhlaste se. Spusťte aplikaci a vyberte Privacy odkaz. Budete přesměrováni na přihlašovací stránku.
Prozkoumat Identity
Podrobnější prozkoumání Identity :
- Vytvoření úplného identity zdroje uživatelského rozhraní
- Prozkoumejte zdroj každé stránky a projděte ladicí program.
Identity Součásti
IdentityVšechny balíčky NuGet závislé na nuGetu jsou součástí sdílené architektury ASP.NET Core.
Primárním balíčkem je Identity Microsoft.AspNetCore.Identity. Tento balíček obsahuje základní sadu rozhraní pro ASP.NET Core Identitya je součástí Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migrace na ASP.NET Core Identity
Další informace a pokyny k migraci stávajícího Identity úložiště najdete v tématu Migrace ověřování a Identity.
Nastavení síly hesla
Viz Konfigurace ukázky, která nastavuje minimální požadavky na heslo.
Zabránění publikování statických Identity prostředků
Pokud chcete zabránit publikování statických Identity prostředků (šablon stylů a souborů JavaScriptu pro Identity uživatelské rozhraní) do kořenového adresáře webu, přidejte do souboru projektu aplikace následující ResolveStaticWebAssetsInputsDependsOn
vlastnost a RemoveIdentityAssets
cíl:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Další kroky
- zdrojový kód ASP.NET Core Identity
- Zdroj AddDefaultIdentity
- Informace o konfiguraci Identity pomocí SQLite najdete v tomto problému s GitHubem.
- Konfigurovat Identity
- Vytvoření aplikace ASP.NET Core s uživatelskými daty chráněnými autorizací
- Přidání, stažení a odstranění uživatelských dat do Identity projektu ASP.NET Core
- Povolení generování kódu QR pro ověřovací aplikace TOTP v ASP.NET Core
- Migrace ověřování a Identity ASP.NET Core
- Potvrzení účtu a obnovení hesla v ASP.NET Core
- Dvoufaktorové ověřování pomocí SMS v ASP.NET Core
- Hostování ASP.NET Core ve webové farmě