Inleiding tot Identity op ASP.NET Core
Door Rick Anderson
ASP.NET Core-Identity:
- Is een API die aanmeldingsfunctionaliteit van de gebruikersinterface (UI) ondersteunt.
- Beheert gebruikers, wachtwoorden, profielgegevens, rollen, claims, tokens, e-mailbevestiging en meer.
Gebruikers kunnen een account maken met de aanmeldingsgegevens die zijn opgeslagen in Identity of ze kunnen een externe aanmeldingsprovider gebruiken. Ondersteunde externe aanmeldingsproviders zijn Facebook, Google, Microsoft-account en Twitter-.
Zie Geverifieerde gebruikers vereisenvoor informatie over het globaal vereisen van verificatie van alle gebruikers.
De Identity broncode is beschikbaar op GitHub. Scaffold Identity en bekijk de gegenereerde bestanden om de interactie met sjabloon Identityte beoordelen.
Identity wordt doorgaans geconfigureerd met behulp van een SQL Server-database voor het opslaan van gebruikersnamen, wachtwoorden en profielgegevens. U kunt ook een ander permanent archief gebruiken, bijvoorbeeld Azure Table Storage.
In dit onderwerp leert u hoe u Identity kunt gebruiken om een gebruiker te registreren, aan te melden en af te melden. Opmerking: de sjablonen behandelen gebruikersnaam en e-mail als dezelfde voor gebruikers. Zie Volgende stappenvoor meer gedetailleerde instructies over het maken van apps die gebruikmaken van Identity.
ASP.NET Core Identity is niet gerelateerd aan het Microsoft Identity Platform. Microsoft Identity Platform is:
- Een evolutie van het Azure Ad-ontwikkelaarsplatform (Azure Active Directory).
- Een alternatieve identiteitsoplossing voor verificatie en autorisatie in ASP.NET Core-apps.
ASP.NET Core Identity voegt de aanmeldingsfunctionaliteit van de gebruikersinterface (UI) toe aan ASP.NET Core-web-apps. Gebruik een van de volgende manieren om web-API's en SPA's te beveiligen:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server is een OpenID Connect- en OAuth 2.0-framework voor ASP.NET Core. Duende Identity Server maakt de volgende beveiligingsfuncties mogelijk:
- Verificatie als een service (AaaS)
- Eenmalige aanmelding/uit (SSO) voor meerdere toepassingstypen
- Toegangsbeheer voor API's
- Federatieve gateway
Belangrijk
Duende Software moet u mogelijk een licentiekosten betalen voor productiegebruik van Duende Identity Server. Zie Migreren van ASP.NET Core 5.0 naar 6.0voor meer informatie.
Zie de Duende Identity Server-documentatie (Duende Software-website)voor meer informatie.
De voorbeeldcode bekijken of downloaden (hoe te downloaden).
Een web-app maken met verificatie
Maak een ASP.NET Core Web Application-project met afzonderlijke gebruikersaccounts.
- Selecteer de sjabloon ASP.NET Core Web App. Geef het project WebApp1 de naam zodat het dezelfde naamruimte heeft als de project download. Klik op OK-.
- Selecteer in het verificatietype invoer afzonderlijke gebruikersaccounts.
Het gegenereerde project biedt ASP.NET Core Identity als een Razor class library. De IdentityRazor classbibliotheek biedt toegang tot eindpunten binnen het Identity
gebied. Bijvoorbeeld:
- /Identity/Account/Aanmelding
- /Identity/Account/Uitloggen
- /Identity/Account/Beheren
Migraties toepassen
Pas de migraties toe voor het initialiseren van de database.
Voer de volgende opdracht uit in de Package Manager Console (PMC):
Update-Database
Registratie en inloggen testen
Voer de app uit en registreer een gebruiker. Afhankelijk van de schermgrootte moet u mogelijk de navigatie-wisselknop selecteren om de koppelingen Registreren en Inloggen te zien.
De Identity-database weergeven
- Vanuit het menu Weergave selecteer SQL Server Object Explorer (SSOX).
- Navigeer naar (localdb)MSSQLLocalDB(SQL Server 13). Klik met de rechtermuisknop op dbo. AspNetUsers>Gegevens weergeven:
Identity-services configureren
Services worden toegevoegd in Program.cs
. Het gebruikelijke patroon is het aanroepen van methoden in de volgende volgorde:
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();
De voorgaande code configureert Identity met standaardoptiewaarden. Services worden beschikbaar gemaakt voor de app via afhankelijkheidsinjectie.
Identity is ingeschakeld door UseAuthenticationaan te roepen.
UseAuthentication
voegt verificatie-middleware- toe aan de aanvraagpijplijn.
De door de sjabloon gegenereerde app maakt geen gebruik van autorisatie.
app.UseAuthorization
is opgenomen om ervoor te zorgen dat deze in de juiste volgorde wordt toegevoegd als de app autorisatie toevoegt.
UseRouting
, UseAuthentication
en UseAuthorization
moeten worden aangeroepen in de volgorde die in de voorgaande code wordt weergegeven.
Zie IdentityOptions en Application Startupvoor meer informatie over IdentityOptions
.
Scaffold Registreren, Inloggen, Uitloggen en Registratiebevestiging
Voeg de bestanden Register
, Login
, LogOut
en RegisterConfirmation
toe. Volg de Scaffold identiteit naar een Razor-project met autorisatie-instructies voor het genereren van code zoals in deze sectie weergegeven.
Register onderzoeken
Wanneer een gebruiker op de knop Registreren op de pagina Register
klikt, wordt de actie RegisterModel.OnPostAsync
aangeroepen. De gebruiker wordt gemaakt door CreateAsync(TUser) op het _userManager
-object:
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();
}
Standaardaccountverificatie uitschakelen
Met de standaardsjablonen wordt de gebruiker omgeleid naar de Account.RegisterConfirmation
waar ze een koppeling kunnen selecteren om het account te laten bevestigen. De standaard Account.RegisterConfirmation
wordt gebruikt alleen voor testen. Automatische accountverificatie moet worden uitgeschakeld in een productie-app.
Als u een bevestigd account wilt vereisen en onmiddellijke aanmelding bij de registratie wilt voorkomen, stelt u DisplayConfirmAccountLink = false
in /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
in:
[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();
}
}
Aanmelden
Het aanmeldingsformulier wordt weergegeven wanneer:
- De Aanmelden koppeling is geselecteerd.
- Een gebruiker probeert toegang te krijgen tot een beperkte pagina waar ze geen toestemming voor hebben, of, wanneer ze niet door het systeem zijn geverifieerd.
Wanneer het formulier op de aanmeldingspagina wordt verzonden, wordt de actie OnPostAsync
aangeroepen.
PasswordSignInAsync
wordt aangeroepen op het _signInManager
-object.
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();
}
Zie Inleiding tot autorisatie in ASP.NET Corevoor meer informatie over het nemen van autorisatiebeslissingen.
Uitloggen
De afmelden koppeling roept de actie LogoutModel.OnPost
aan.
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();
}
}
}
}
In de voorgaande code moet de code return RedirectToPage();
een omleiding zijn, zodat de browser een nieuwe aanvraag uitvoert en de identiteit voor de gebruiker wordt bijgewerkt.
SignOutAsync wist de claims van de gebruiker die zijn opgeslagen in een cookie.
Post is opgegeven in de 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
Met de standaardwebprojectsjablonen is anonieme toegang tot de startpagina's toegestaan. Als u Identitywilt testen, voegt u [Authorize]
toe:
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()
{
}
}
}
Als u bent aangemeld, meldt u zich af. Voer de app uit en selecteer de koppeling Privacy. U wordt omgeleid naar de aanmeldingspagina.
Verken Identity
Meer informatie over Identity:
- Volledige identiteits-UI bron maken
- Bekijk de bron van elke pagina en doorloop het foutopsporingsprogramma.
Identity-onderdelen
Alle Identity-afhankelijke NuGet-pakketten zijn opgenomen in het ASP.NET Core-gedeelde framework.
Het primaire pakket voor Identity is Microsoft.AspNetCore.Identity. Dit pakket bevat de kernset interfaces voor ASP.NET Core Identityen is opgenomen in Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migreren naar ASP.NET Core-Identity
Voor meer informatie en richtlijnen over het migreren van uw bestaande Identity winkel, zie Verificatie migreren en Identity.
Wachtwoordsterkte instellen
Zie Configuration voor een voorbeeld waarmee de minimale wachtwoordvereisten worden ingesteld.
AddDefaultIdentity en AddIdentity
AddDefaultIdentity werd geïntroduceerd in ASP.NET Core 2.1. Bellen AddDefaultIdentity
is vergelijkbaar met het aanroepen van het volgende:
Zie AddDefaultIdentity-bron voor meer informatie.
Publicatie van statische Identity assets voorkomen
Om te voorkomen dat statische Identity assets (opmaakmodellen en JavaScript-bestanden voor Identity gebruikersinterface) naar de webroot worden gepubliceerd, voeg de volgende ResolveStaticWebAssetsInputsDependsOn
eigenschap en RemoveIdentityAssets
doel toe aan het projectbestand van de app:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Volgende stappen
- Zie dit GitHub-probleem voor informatie over het configureren van Identity met sqlite.
- Identity configureren
- Een ASP.NET Core-app maken met gebruikersgegevens die worden beveiligd door autorisatie-
- gebruikersgegevens toevoegen, downloaden en verwijderen uit Identity in een ASP.NET Core-project
- het genereren van QR-code inschakelen voor TOTP Authenticator-apps in ASP.NET Core
- Verificatie en Identity migreren naar ASP.NET Core-
- Accountbevestiging en Wachtwoordherstel in ASP.NET Core
- tweeledige verificatie met SMS in ASP.NET Core
- Host ASP.NET Core in een webfarm
Door Rick Anderson
ASP.NET Core-Identity:
- Is een API die aanmeldingsfunctionaliteit van de gebruikersinterface (UI) ondersteunt.
- Beheert gebruikers, wachtwoorden, profielgegevens, rollen, claims, tokens, e-mailbevestiging en meer.
Gebruikers kunnen een account maken met de aanmeldingsgegevens die zijn opgeslagen in Identity of ze kunnen een externe aanmeldingsprovider gebruiken. Ondersteunde externe aanmeldingsproviders zijn Facebook, Google, Microsoft-account en Twitter-.
Zie Geverifieerde gebruikers vereisenvoor informatie over het globaal vereisen van verificatie van alle gebruikers.
De Identity broncode is beschikbaar op GitHub. Scaffold Identity en bekijk de gegenereerde bestanden om de interactie van de sjabloon met Identityte controleren.
Identity wordt doorgaans geconfigureerd met behulp van een SQL Server-database voor het opslaan van gebruikersnamen, wachtwoorden en profielgegevens. U kunt ook een ander permanent archief gebruiken, bijvoorbeeld Azure Table Storage.
In dit onderwerp leert u hoe u Identity kunt gebruiken om een gebruiker te registreren, aan te melden en af te melden. Opmerking: de sjablonen behandelen gebruikersnaam en e-mail als dezelfde voor gebruikers. Zie Volgende stappenvoor meer gedetailleerde instructies over het maken van apps die gebruikmaken van Identity.
Microsoft Identity Platform is:
- Een evolutie van het Azure Ad-ontwikkelaarsplatform (Azure Active Directory).
- Een alternatieve identiteitsoplossing voor verificatie en autorisatie in ASP.NET Core-apps.
- Niet gerelateerd aan ASP.NET Core Identity.
ASP.NET Core Identity voegt de aanmeldingsfunctionaliteit van de gebruikersinterface (UI) toe aan ASP.NET Core-web-apps. Gebruik een van de volgende manieren om web-API's en SPA's te beveiligen:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. Duende IdentityServer is een product van derden.
Duende IdentityServer is een OpenID Connect- en OAuth 2.0-framework voor ASP.NET Core. Duende IdentityServer maakt de volgende beveiligingsfuncties mogelijk:
- Verificatie als een service (AaaS)
- Eenmalige aanmelding/uit (SSO) voor meerdere toepassingstypen
- Toegangsbeheer voor API's
- Federatieve gateway
Zie Overzicht van Duende IdentityServervoor meer informatie.
Raadpleeg Community OSS-verificatieopties voor ASP.NET Core voor meer informatie over andere authenticatieproviders.
De voorbeeldcode bekijken of downloaden (hoe te downloaden).
Een web-app maken met verificatie
Maak een ASP.NET Core Web Application-project met afzonderlijke gebruikersaccounts.
- Selecteer Bestand>Nieuw>Project.
- Selecteer ASP.NET Core Web Application. Geef het project WebApp1 dezelfde naamruimte als de namespace van de projectdownload. Klik op OK-.
- Selecteer een ASP.NET Core Web Applicationen selecteer vervolgens Verificatie wijzigen.
- Selecteer afzonderlijke gebruikersaccounts en klik op OK.
Het gegenereerde project biedt ASP.NET Core Identity als een Razor class library. De IdentityRazor classbibliotheek ontsluit eindpunten binnen het Identity
domein. Bijvoorbeeld:
- /Identity/Account/Aanmelding
- /Identity/Account/Uitloggen
- /Identity/Account/Beheren
Migraties toepassen
Pas de migraties toe om de database te initialiseren.
Voer de volgende opdracht uit in de Package Manager Console (PMC):
PM> Update-Database
Registreren en aanmelden testen
Voer de app uit en registreer een gebruiker. Afhankelijk van de schermgrootte moet u mogelijk de navigatiewisselknop selecteren om de Registreren en Inloggen koppelingen te zien.
De Identity-database weergeven
- In het menu Weergave, selecteer SQL Server Object Explorer (SSOX).
- Navigeer naar (localdb)MSSQLLocalDB(SQL Server 13). Klik met de rechtermuisknop op dbo. AspNetUsers>Gegevens weergeven:
De Identity-services configureren
Diensten worden toegevoegd in ConfigureServices
. Het typische patroon is om alle Add{Service}
methoden aan te roepen en vervolgens alle services.Configure{Service}
methoden aan te roepen.
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;
});
}
De voorgaande gemarkeerde code configureert Identity met standaardoptiewaarden. Diensten worden via afhankelijkheidsinjectieaan de app beschikbaar gesteld.
Identity is ingeschakeld door UseAuthenticationaan te roepen.
UseAuthentication
voegt de middleware voor authenticatie toe aan de aanvraagpijplijn.
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;
});
}
De voorgaande code configureert Identity met standaardoptiewaarden. De app krijgt toegang tot services via afhankelijkheidsinjectie.
Identity is ingeschakeld door UseAuthenticationaan te roepen.
UseAuthentication
voegt authenticatie middleware toe aan de aanvraagpijplijn.
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();
});
}
De door de sjabloon gegenereerde app maakt geen gebruik van autorisatie.
app.UseAuthorization
is opgenomen om ervoor te zorgen dat deze in de juiste volgorde wordt toegevoegd als de app autorisatie toevoegt.
UseRouting
, UseAuthentication
, UseAuthorization
en UseEndpoints
moeten worden aangeroepen in de volgorde die in de voorgaande code wordt weergegeven.
Zie IdentityOptions en Application Startupvoor meer informatie over IdentityOptions
en Startup
.
Stel Registreer, Inloggen, Uitloggen en Registratiebevestiging op
Voeg de bestanden Register
, Login
, LogOut
en RegisterConfirmation
toe. Volg de Scaffold-identiteit in een Razor project met autorisatie instructies voor het genereren van de code die in deze sectie wordt weergegeven.
Register onderzoeken
Wanneer een gebruiker op de knop Registreren op de pagina Register
klikt, wordt de actie RegisterModel.OnPostAsync
aangeroepen. De gebruiker wordt gemaakt door CreateAsync(TUser) op het _userManager
-object:
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();
}
Verificatie van standaardaccount uitschakelen
Met de standaardsjablonen wordt de gebruiker omgeleid naar de Account.RegisterConfirmation
waar ze een koppeling kunnen selecteren om het account te laten bevestigen. De standaard Account.RegisterConfirmation
wordt gebruikt alleen voor testen, automatische accountverificatie moet worden uitgeschakeld in een productieapplicatie.
Als u een bevestigd account wilt vereisen en onmiddellijke aanmelding bij de registratie wilt voorkomen, stelt u DisplayConfirmAccountLink = false
in /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
in:
[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();
}
}
Aanmelden
Het aanmeldingsformulier wordt weergegeven wanneer:
- De link Inloggen bij is geselecteerd.
- Een gebruiker probeert toegang te krijgen tot een beperkte pagina, of, waarvoor hij/zij geen toestemming heeft, wanneer hij/zij niet door het systeem is geverifieerd.
Wanneer het formulier op de aanmeldingspagina wordt verzonden, wordt de actie OnPostAsync
aangeroepen.
PasswordSignInAsync
wordt aangeroepen op het _signInManager
-object.
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();
}
Zie Inleiding tot autorisatie in ASP.NET Corevoor meer informatie over het nemen van autorisatiebeslissingen.
Uitloggen
De afmelden koppeling roept de actie LogoutModel.OnPost
aan.
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();
}
}
}
}
In de voorgaande code moet de code return RedirectToPage();
een omleiding zijn, zodat de browser een nieuwe aanvraag uitvoert en de identiteit voor de gebruiker wordt bijgewerkt.
SignOutAsync wist de claims van de gebruiker die zijn opgeslagen in een cookie.
Post is opgegeven in de 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
Met de standaardwebprojectsjablonen is anonieme toegang tot de startpagina's toegestaan. Als u Identitywilt testen, voegt u [Authorize]
toe:
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()
{
}
}
}
Als u bent aangemeld, meldt u zich af. Voer de app uit en selecteer de koppeling Privacy. U wordt omgeleid naar de aanmeldingspagina.
Verken Identity
Meer informatie over Identity:
- Volledige identiteit UI-bron creëren
- Bekijk de bron van elke pagina en doorloop het foutopsporingsprogramma.
Identity-onderdelen
Alle Identity-afhankelijke NuGet-pakketten zijn opgenomen in het ASP.NET Core-gedeelde framework.
Het primaire pakket voor Identity is Microsoft.AspNetCore.Identity. Dit pakket bevat de kernset interfaces voor ASP.NET Core Identityen is opgenomen in Microsoft.AspNetCore.Identity.EntityFrameworkCore
.
Migreren naar ASP.NET Core-Identity
Voor meer informatie en richtlijnen over het migreren van uw bestaande Identity winkel, zie Migratie van authenticatie en Identity.
Wachtwoordsterkte instellen
Zie Configuration voor een voorbeeld waarmee de minimale wachtwoordvereisten worden ingesteld.
Voorkom de publicatie van statische Identity assets
Als u wilt voorkomen dat statische Identity assets (opmaakmodellen en JavaScript-bestanden voor Identity gebruikersinterface) worden gepubliceerd naar de web-root, voegt u de volgende ResolveStaticWebAssetsInputsDependsOn
eigenschap en RemoveIdentityAssets
target toe aan het projectbestand van de app.
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Volgende stappen
- ASP.NET Core Identity broncode
- AddDefaultIdentity-bron
- Zie dit GitHub-probleem voor informatie over het configureren van Identity met sqlite.
- Configureren Identity
- Een ASP.NET Core-app maken met gebruikersgegevens die worden beveiligd door autorisatie-
- gebruikersgegevens toevoegen, downloaden en verwijderen uit Identity in een ASP.NET Core-project
- Het genereren van een QR-code inschakelen voor TOTP Authenticator-apps in ASP.NET Core
- Verificatie en Identity migreren naar ASP.NET Core-
- Accountbevestiging en Wachtwoordherstel in ASP.NET Core
- tweeledige verificatie met SMS in ASP.NET Core
- Host ASP.NET Core in een webfarm