Wprowadzenie do Identity ASP.NET Core
Autor: Rick Anderson
ASP.NET Core Identity:
- To interfejs API, który obsługuje funkcje logowania interfejsu użytkownika.
- Zarządza użytkownikami, hasłami, danymi profilu, rolami, oświadczeniami, tokenami, potwierdzeniem wiadomości e-mail i nie tylko.
Użytkownicy mogą utworzyć konto przy użyciu informacji logowania przechowywanych w Identity programie lub użyć zewnętrznego dostawcy logowania. Obsługiwani zewnętrzni dostawcy logowania to Facebook , Google, Konto Microsoft i Twitter.
Aby uzyskać informacje na temat globalnego wymagania uwierzytelnienia wszystkich użytkowników, zobacz Wymaganie uwierzytelnionych użytkowników.
Kod Identity źródłowy jest dostępny w witrynie GitHub. Identity Tworzenie szkieletu i wyświetlanie wygenerowanych plików w celu przejrzenia interakcji szablonu z Identityprogramem .
Identity Program jest zwykle konfigurowany przy użyciu bazy danych programu SQL Server do przechowywania nazw użytkowników, haseł i danych profilu. Alternatywnie można użyć innego magazynu trwałego, na przykład usługi Azure Table Storage.
W tym temacie dowiesz się, jak zarejestrować, zalogować się i wylogować Identity użytkownika. Uwaga: szablony traktują nazwę użytkownika i adres e-mail jako taki sam dla użytkowników. Aby uzyskać bardziej szczegółowe instrukcje dotyczące tworzenia aplikacji korzystających z usługi Identity, zobacz Następne kroki.
ASP.NET Core Identity nie jest powiązany z Platforma tożsamości Microsoft. Platforma tożsamości Microsoft to:
- Ewolucja platformy deweloperów usługi Azure Active Directory (Azure AD).
- Alternatywne rozwiązanie do obsługi tożsamości na potrzeby uwierzytelniania i autoryzacji w aplikacjach platformy ASP.NET Core.
ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:
Duende Identity Server to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identity umożliwia korzystanie z następujących funkcji zabezpieczeń:
- Uwierzytelnianie jako usługa (AaaS)
- Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
- Kontrola dostępu dla interfejsów API
- Brama federacyjna
Ważne
Oprogramowanie Duende może wymagać zapłacenia opłaty licencyjnej za korzystanie z serwera Duende Identity Server w środowisku produkcyjnym. Aby uzyskać więcej informacji, zobacz Migracja z platformy ASP.NET Core w wersji 5.0 do wersji 6.0.
Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).
Wyświetl lub pobierz przykładowy kod (jak pobrać).
Tworzenie aplikacji internetowej z uwierzytelnianiem
Utwórz projekt aplikacji internetowej platformy ASP.NET Core przy użyciu indywidualnych kont użytkowników.
- Wybierz szablon aplikacji internetowej ASP.NET Core. Nadaj projektowi nazwę WebApp1 tak, aby miała taką samą przestrzeń nazw jak pobieranie projektu. Kliknij przycisk OK.
- W polu danych wejściowych Typ uwierzytelniania wybierz pozycję Pojedyncze konta użytkowników.
Wygenerowany projekt udostępnia ASP.NET Core Identity jako bibliotekę Razorklas. Biblioteka IdentityRazor klas uwidacznia punkty końcowe w Identity
obszarze. Na przykład:
- /Identity/Konto/Logowanie
- /Identity/Konto/Wylogowywanie
- /Identity/Konto/Zarządzanie
Stosowanie migracji
Zastosuj migracje, aby zainicjować bazę danych.
Uruchom następujące polecenie w konsoli Menedżer pakietów (PMC):
Update-Database
Testowanie rejestracji i logowania
Uruchom aplikację i zarejestruj użytkownika. W zależności od rozmiaru ekranu może być konieczne wybranie przycisku przełącznika nawigacji, aby wyświetlić linki Zarejestruj i Zaloguj .
Identity Wyświetlanie bazy danych
- Z menu Widok wybierz pozycję SQL Server Eksplorator obiektów (SSOX).
- Przejdź do (localdb)MSSQLLocalDB(SQL Server 13). Kliknij prawym przyciskiem myszy pozycję dbo. Dane widoku aspNetUsers>:
Konfigurowanie Identity usług
Usługi są dodawane w programie Program.cs
. Typowy wzorzec polega na wywołaniu metod w następującej kolejności:
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();
Powyższy kod konfiguruje Identity z domyślnymi wartościami opcji. Usługi są udostępniane aplikacji za pośrednictwem wstrzykiwania zależności.
Identity jest włączona przez wywołanie metody UseAuthentication. UseAuthentication
Dodaje oprogramowanie pośredniczące uwierzytelniania do potoku żądania.
Aplikacja wygenerowana przez szablon nie używa autoryzacji. app.UseAuthorization
element jest uwzględniony, aby upewnić się, że jest dodawany w odpowiedniej kolejności, jeśli aplikacja doda autoryzację. UseRouting
, UseAuthentication
i UseAuthorization
musi być wywoływana w kolejności pokazanej w poprzednim kodzie.
Aby uzyskać więcej informacji na temat IdentityOptions
programu , zobacz IdentityOptions i Uruchamianie aplikacji.
Rejestrowanie szkieletu, logowanie, rejestrowanie i rejestrowanieKonfirmacja
Register
Dodaj pliki , Login
, LogOut
i RegisterConfirmation
. Postępuj zgodnie z tożsamością szkieletu w Razor projekcie z instrukcjami autoryzacji , aby wygenerować kod pokazany w tej sekcji.
Sprawdzanie rejestru
Gdy użytkownik kliknie przycisk Zarejestruj na Register
stronie, RegisterModel.OnPostAsync
zostanie wywołana akcja. Użytkownik jest tworzony przez CreateAsync(TUser) użytkownika w _userManager
obiekcie :
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();
}
Wyłącz domyślną weryfikację konta
W przypadku szablonów domyślnych użytkownik jest przekierowywany do Account.RegisterConfirmation
lokalizacji, w której może wybrać link, aby potwierdzić konto. Wartość domyślna Account.RegisterConfirmation
jest używana tylko do testowania, automatyczna weryfikacja konta powinna być wyłączona w aplikacji produkcyjnej.
Aby wymagać potwierdzonego konta i zapobiec natychmiastowemu zalogowaniu podczas rejestracji, ustaw wartość w pliku DisplayConfirmAccountLink = false
/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();
}
}
Logowanie się
Formularz logowania jest wyświetlany, gdy:
- Wybrano link Zaloguj .
- Użytkownik próbuje uzyskać dostęp do strony z ograniczeniami, do której nie ma uprawnień dostępu lub gdy nie został uwierzytelniony przez system.
Po przesłaniu formularza na stronie Logowania akcja jest wywoływana OnPostAsync
. PasswordSignInAsync
element jest wywoływany _signInManager
na obiekcie .
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();
}
Aby uzyskać informacje na temat podejmowania decyzji dotyczących autoryzacji, zobacz Wprowadzenie do autoryzacji w programie ASP.NET Core.
Wyloguj się
Link WylogujLogoutModel.OnPost
wywołuje akcję.
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();
}
}
}
}
W poprzednim kodzie kod return RedirectToPage();
musi być przekierowaniem, aby przeglądarka wykonała nowe żądanie, a tożsamość użytkownika zostanie zaktualizowana.
SignOutAsync czyści oświadczenia użytkownika przechowywane w obiekcie cookie.
Wpis jest określony w pliku 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
Domyślne szablony projektów internetowych umożliwiają anonimowy dostęp do stron domowych. Aby przetestować Identitypolecenie , dodaj polecenie [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()
{
}
}
}
Jeśli się zalogujesz, wyloguj się. Uruchom aplikację i wybierz Privacy link. Nastąpi przekierowanie do strony logowania.
Poznaj Identity
Aby zapoznać się Identity bardziej szczegółowo:
- Tworzenie źródła interfejsu użytkownika pełnej tożsamości
- Sprawdź źródło każdej strony i wykonaj kroki przez debuger.
Identity Składniki
IdentityWszystkie pakiety NuGet zależne są zawarte w strukturze udostępnionej ASP.NET Core.
Podstawowym pakietem programu Identity jest Microsoft.AspNetCore.Identity. Ten pakiet zawiera podstawowy zestaw interfejsów dla ASP.NET Core Identityi jest uwzględniony przez Microsoft.AspNetCore.Identity.EntityFrameworkCore
program .
Migrowanie do platformy ASP.NET Core Identity
Aby uzyskać więcej informacji i wskazówek dotyczących migrowania istniejącego Identity magazynu, zobacz Migrowanie uwierzytelniania i Identity.
Ustawianie siły hasła
Zobacz Konfiguracja przykładu, który określa minimalne wymagania dotyczące hasła.
AddDefaultIdentity i AddIdentity
AddDefaultIdentity wprowadzono w ASP.NET Core 2.1. Wywołanie AddDefaultIdentity
jest podobne do wywołania następującego:
Aby uzyskać więcej informacji, zobacz AddDefault source (Źródło addDefaultIdentity).
Zapobieganie publikowaniu zasobów statycznych Identity
Aby zapobiec publikowaniu statycznych Identity zasobów (arkuszy stylów i plików JavaScript dla Identity interfejsu użytkownika) w katalogu głównym sieci Web, dodaj następującą ResolveStaticWebAssetsInputsDependsOn
właściwość i RemoveIdentityAssets
element docelowy do pliku projektu aplikacji:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Następne kroki
- kod źródłowy platformy ASP.NET Core Identity
- Jak pracować z rolami w programie ASP.NET Core Identity
- Zobacz ten problem z usługą GitHub, aby uzyskać informacje na temat konfigurowania Identity przy użyciu biblioteki SQLite.
- Skonfigurować Identity
- Tworzenie aplikacji platformy ASP.NET Core przy użyciu danych użytkowników chronionych przez autoryzację
- Dodawanie, pobieranie i usuwanie danych użytkownika w Identity projekcie ASP.NET Core
- Włączanie generowania kodu QR dla aplikacji uwierzytelniającego TOTP w usłudze ASP.NET Core
- Migrowanie uwierzytelniania i Identity do ASP.NET Core
- Potwierdzenie konta i odzyskiwanie hasła w usłudze ASP.NET Core
- Uwierzytelnianie dwuskładnikowe z wiadomością SMS w programie ASP.NET Core
- Hostowanie aplikacji ASP.NET Core na farmie internetowej
Autor: Rick Anderson
ASP.NET Core Identity:
- To interfejs API, który obsługuje funkcje logowania interfejsu użytkownika.
- Zarządza użytkownikami, hasłami, danymi profilu, rolami, oświadczeniami, tokenami, potwierdzeniem wiadomości e-mail i nie tylko.
Użytkownicy mogą utworzyć konto przy użyciu informacji logowania przechowywanych w Identity programie lub użyć zewnętrznego dostawcy logowania. Obsługiwani zewnętrzni dostawcy logowania to Facebook , Google, Konto Microsoft i Twitter.
Aby uzyskać informacje na temat globalnego wymagania uwierzytelnienia wszystkich użytkowników, zobacz Wymaganie uwierzytelnionych użytkowników.
Kod Identity źródłowy jest dostępny w witrynie GitHub. Identity Tworzenie szkieletu i wyświetlanie wygenerowanych plików w celu przejrzenia interakcji szablonu z Identityprogramem .
Identity Program jest zwykle konfigurowany przy użyciu bazy danych programu SQL Server do przechowywania nazw użytkowników, haseł i danych profilu. Alternatywnie można użyć innego magazynu trwałego, na przykład usługi Azure Table Storage.
W tym temacie dowiesz się, jak zarejestrować, zalogować się i wylogować Identity użytkownika. Uwaga: szablony traktują nazwę użytkownika i adres e-mail jako taki sam dla użytkowników. Aby uzyskać bardziej szczegółowe instrukcje dotyczące tworzenia aplikacji korzystających z usługi Identity, zobacz Następne kroki.
Platforma tożsamości Microsoft to:
- Ewolucja platformy deweloperów usługi Azure Active Directory (Azure AD).
- Alternatywne rozwiązanie do obsługi tożsamości na potrzeby uwierzytelniania i autoryzacji w aplikacjach platformy ASP.NET Core.
- Nie dotyczy ASP.NET Core Identity.
ASP.NET Core Identity dodaje funkcje logowania interfejsu użytkownika do aplikacji internetowych platformy ASP.NET Core. Aby zabezpieczyć internetowe interfejsy API i spA, użyj jednego z następujących elementów:
- Tożsamość Microsoft Entra
- Azure Active Directory B2C (Azure AD B2C )
- Serwer DuendeIdentity. Serwer Duende Identityjest produktem innej firmy.
Duende IdentityServer to platforma OpenID Połączenie i OAuth 2.0 dla platformy ASP.NET Core. Serwer Duende Identityumożliwia korzystanie z następujących funkcji zabezpieczeń:
- Uwierzytelnianie jako usługa (AaaS)
- Logowanie jednokrotne/wyłączanie logowania jednokrotnego w wielu typach aplikacji
- Kontrola dostępu dla interfejsów API
- Brama federacyjna
Aby uzyskać więcej informacji, zobacz Omówienie serwera DuendeIdentity.
Aby uzyskać więcej informacji na temat innych dostawców uwierzytelniania, zobacz Community OSS authentication options for ASP.NET Core (Opcje uwierzytelniania systemu operacyjnego Community dla platformy ASP.NET Core)
Wyświetl lub pobierz przykładowy kod (jak pobrać).
Tworzenie aplikacji internetowej z uwierzytelnianiem
Utwórz projekt aplikacji internetowej platformy ASP.NET Core przy użyciu indywidualnych kont użytkowników.
- Wybierz kolejno pozycje Plik>Nowy>Projekt.
- Wybierz pozycję ASP.NET Core Web Application(Podstawowa aplikacja internetowa). Nadaj projektowi nazwę WebApp1 tak, aby miała taką samą przestrzeń nazw jak pobieranie projektu. Kliknij przycisk OK.
- Wybierz aplikację internetową ASP.NET Core, a następnie wybierz pozycję Zmień uwierzytelnianie.
- Wybierz pozycję Indywidualne konta użytkowników i kliknij przycisk OK.
Wygenerowany projekt udostępnia ASP.NET Core Identity jako bibliotekę Razorklas. Biblioteka IdentityRazor klas uwidacznia punkty końcowe w Identity
obszarze. Na przykład:
- /Identity/Konto/Logowanie
- /Identity/Konto/Wylogowywanie
- /Identity/Konto/Zarządzanie
Stosowanie migracji
Zastosuj migracje, aby zainicjować bazę danych.
Uruchom następujące polecenie w konsoli Menedżer pakietów (PMC):
PM> Update-Database
Testowanie rejestracji i logowania
Uruchom aplikację i zarejestruj użytkownika. W zależności od rozmiaru ekranu może być konieczne wybranie przycisku przełącznika nawigacji, aby wyświetlić linki Zarejestruj i Zaloguj .
Identity Wyświetlanie bazy danych
- Z menu Widok wybierz pozycję SQL Server Eksplorator obiektów (SSOX).
- Przejdź do (localdb)MSSQLLocalDB(SQL Server 13). Kliknij prawym przyciskiem myszy pozycję dbo. Dane widoku aspNetUsers>:
Konfigurowanie Identity usług
Usługi są dodawane w programie ConfigureServices
. Typowy wzorzec polega na wywołaniu wszystkich Add{Service}
metod, a następnie wywołaniu wszystkich services.Configure{Service}
metod.
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;
});
}
Powyższy wyróżniony kod konfiguruje Identity z domyślnymi wartościami opcji. Usługi są udostępniane aplikacji za pośrednictwem wstrzykiwania zależności.
Identity jest włączona przez wywołanie metody UseAuthentication. UseAuthentication
Dodaje oprogramowanie pośredniczące uwierzytelniania do potoku żądania.
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;
});
}
Powyższy kod konfiguruje Identity z domyślnymi wartościami opcji. Usługi są udostępniane aplikacji za pośrednictwem wstrzykiwania zależności.
Identity jest włączona przez wywołanie metody UseAuthentication. UseAuthentication
Dodaje oprogramowanie pośredniczące uwierzytelniania do potoku żądania.
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();
});
}
Aplikacja wygenerowana przez szablon nie używa autoryzacji. app.UseAuthorization
element jest uwzględniony, aby upewnić się, że jest dodawany w odpowiedniej kolejności, jeśli aplikacja doda autoryzację. UseRouting
, , UseAuthentication
UseAuthorization
i UseEndpoints
musi być wywoływana w kolejności pokazanej w poprzednim kodzie.
Aby uzyskać więcej informacji na temat IdentityOptions
i Startup
, zobacz IdentityOptions i Application Startup (Uruchamianie aplikacji).
Rejestrowanie szkieletu, logowanie, rejestrowanie i rejestrowanieKonfirmacja
Register
Dodaj pliki , Login
, LogOut
i RegisterConfirmation
. Postępuj zgodnie z tożsamością szkieletu w Razor projekcie z instrukcjami autoryzacji , aby wygenerować kod pokazany w tej sekcji.
Sprawdzanie rejestru
Gdy użytkownik kliknie przycisk Zarejestruj na Register
stronie, RegisterModel.OnPostAsync
zostanie wywołana akcja. Użytkownik jest tworzony przez CreateAsync(TUser) użytkownika w _userManager
obiekcie :
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();
}
Wyłącz domyślną weryfikację konta
W przypadku szablonów domyślnych użytkownik jest przekierowywany do Account.RegisterConfirmation
lokalizacji, w której może wybrać link, aby potwierdzić konto. Wartość domyślna Account.RegisterConfirmation
jest używana tylko do testowania, automatyczna weryfikacja konta powinna być wyłączona w aplikacji produkcyjnej.
Aby wymagać potwierdzonego konta i zapobiec natychmiastowemu zalogowaniu podczas rejestracji, ustaw wartość w pliku DisplayConfirmAccountLink = false
/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();
}
}
Logowanie się
Formularz logowania jest wyświetlany, gdy:
- Wybrano link Zaloguj .
- Użytkownik próbuje uzyskać dostęp do strony z ograniczeniami, do której nie ma uprawnień dostępu lub gdy nie został uwierzytelniony przez system.
Po przesłaniu formularza na stronie Logowania akcja jest wywoływana OnPostAsync
. PasswordSignInAsync
element jest wywoływany _signInManager
na obiekcie .
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();
}
Aby uzyskać informacje na temat podejmowania decyzji dotyczących autoryzacji, zobacz Wprowadzenie do autoryzacji w programie ASP.NET Core.
Wyloguj się
Link WylogujLogoutModel.OnPost
wywołuje akcję.
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();
}
}
}
}
W poprzednim kodzie kod return RedirectToPage();
musi być przekierowaniem, aby przeglądarka wykonała nowe żądanie, a tożsamość użytkownika zostanie zaktualizowana.
SignOutAsync czyści oświadczenia użytkownika przechowywane w obiekcie cookie.
Wpis jest określony w pliku 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
Domyślne szablony projektów internetowych umożliwiają anonimowy dostęp do stron domowych. Aby przetestować Identitypolecenie , dodaj polecenie [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()
{
}
}
}
Jeśli się zalogujesz, wyloguj się. Uruchom aplikację i wybierz Privacy link. Nastąpi przekierowanie do strony logowania.
Poznaj Identity
Aby zapoznać się Identity bardziej szczegółowo:
- Tworzenie źródła interfejsu użytkownika pełnej tożsamości
- Sprawdź źródło każdej strony i wykonaj kroki przez debuger.
Identity Składniki
IdentityWszystkie pakiety NuGet zależne są zawarte w strukturze udostępnionej ASP.NET Core.
Podstawowym pakietem programu Identity jest Microsoft.AspNetCore.Identity. Ten pakiet zawiera podstawowy zestaw interfejsów dla ASP.NET Core Identityi jest uwzględniony przez Microsoft.AspNetCore.Identity.EntityFrameworkCore
program .
Migrowanie do platformy ASP.NET Core Identity
Aby uzyskać więcej informacji i wskazówek dotyczących migrowania istniejącego Identity magazynu, zobacz Migrowanie uwierzytelniania i Identity.
Ustawianie siły hasła
Zobacz Konfiguracja przykładu, który określa minimalne wymagania dotyczące hasła.
Zapobieganie publikowaniu zasobów statycznych Identity
Aby zapobiec publikowaniu statycznych Identity zasobów (arkuszy stylów i plików JavaScript dla Identity interfejsu użytkownika) w katalogu głównym sieci Web, dodaj następującą ResolveStaticWebAssetsInputsDependsOn
właściwość i RemoveIdentityAssets
element docelowy do pliku projektu aplikacji:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Następne kroki
- kod źródłowy platformy ASP.NET Core Identity
- DodajDomyślneIdentity źródło
- Zobacz ten problem z usługą GitHub, aby uzyskać informacje na temat konfigurowania Identity przy użyciu biblioteki SQLite.
- Skonfigurować Identity
- Tworzenie aplikacji platformy ASP.NET Core przy użyciu danych użytkowników chronionych przez autoryzację
- Dodawanie, pobieranie i usuwanie danych użytkownika w Identity projekcie ASP.NET Core
- Włączanie generowania kodu QR dla aplikacji uwierzytelniającego TOTP w usłudze ASP.NET Core
- Migrowanie uwierzytelniania i Identity do ASP.NET Core
- Potwierdzenie konta i odzyskiwanie hasła w usłudze ASP.NET Core
- Uwierzytelnianie dwuskładnikowe z wiadomością SMS w programie ASP.NET Core
- Hostowanie aplikacji ASP.NET Core na farmie internetowej