Udostępnij za pośrednictwem


Wprowadzenie do Identity w ASP.NET Core

ASP.NET Core Identity:

  • To API, które obsługuje logowanie w interfejsie 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. Twórz szkielet Identity i wyświetlaj wygenerowane pliki, aby przejrzeć interakcję szablonu z Identity.

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 używać Identity do zarejestrowania, zalogowania i wylogowania 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.

Aby uzyskać więcej informacji na temat Identity w aplikacjach Blazor, zobacz Blazor oraz artykuły, które następują po niej w dokumentacji .

ASP.NET Core Identity nie jest powiązana z platformą tożsamości Microsoft. Platforma tożsamości firmy 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ć interfejsy API dla aplikacji webowych i SPA, użyj jednej z następujących opcji:

Duende Identity Server to platforma OpenID Connect 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/wylogowanie jednokrotne 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 Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

Aby uzyskać więcej informacji, zobacz dokumentację serwera Duende (witryna internetowa Duende Identity Software).

Wyświetl lub pobierz przykładowy kod (jak pobrać).

Utwórz Blazor Web App z uwierzytelnianiem

Utwórz projekt ASP.NET Core Blazor Web App przy użyciu indywidualnych kont.

Uwaga

Aby uzyskać doświadczenie Razor Pages, zobacz sekcję Stwórz aplikację Razor Pages z uwierzytelnianiem.

Aby uzyskać informacje o środowisku MVC, zobacz sekcję Tworzenie aplikacji MVC z uwierzytelnianiem .

  • Blazor Web App Wybierz szablon. Wybierz Dalej.
  • Wybierz następujące opcje:
    • Typ uwierzytelniania: Indywidualne konta
    • Tryb renderowania interakcyjnego: serwer
    • Lokalizacja interakcyjności: globalna
  • Wybierz Utwórz.

Wygenerowany projekt zawiera IdentityRazor składniki. Składniki znajdują się w folderze Components/Account . Na przykład:

  • /Components/Account/Pages/Register
  • /Components/Account/Pages/Login
  • /Components/Account/Pages/Manage/ChangePassword

Identity Razor składniki są opisane indywidualnie w dokumentacji dla określonych przypadków użycia i mogą ulec zmianie w każdej wersji. Podczas generowania elementu przy Blazor Web App użyciu indywidualnych kont IdentityRazor składniki są uwzględniane w wygenerowanym projekcie. Składniki IdentityRazor można również sprawdzić w szablonie projektu Blazor w źródle referencyjnym ASP.NET Core (dotnet/aspnetcorerepozytorium GitHub).

Uwaga

Linki dokumentacyjne do źródła referencyjnego .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla obecne prace rozwojowe nad nadchodzącą wersją .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Aby uzyskać więcej informacji, zobacz uwierzytelnianie i autoryzację ASP.NET CoreBlazor oraz kolejne artykuły znajdujące się w tej dokumentacji. Większość artykułów w obszarze Zabezpieczenia i Identity w głównym zestawie dokumentacji ASP.NET Core ma zastosowanie do Blazor aplikacji. Blazor Jednak zestaw dokumentacji zawiera artykuły i wskazówki, które zastępują lub dodaje informacje. Zalecamy najpierw zapoznanie się z ogólnym zestawem dokumentacji ASP.NET Core, a następnie uzyskanie dostępu do artykułów w artykule BlazorZabezpieczenia i Identity dokumentacja.

Tworzenie aplikacji Pages z uwierzytelnianiem Razor

Utwórz projekt ASP.NET Core Web Application (Razor Pages) przy użyciu indywidualnych kont.

  • Wybierz szablon ASP.NET Core Web App (Razorstrony). Wybierz Dalej.
  • W polu Typ uwierzytelniania wybierz pozycję Indywidualne konta.
  • Wybierz Utwórz.

Wygenerowany projekt udostępnia ASP.NET Core Identity jako bibliotekęRazor klas (RCL). Biblioteka IdentityRazor klas uwidacznia punkty końcowe w Identity obszarze. Na przykład:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

Strony są opisane indywidualnie w dokumentacji dla określonych przypadków użycia i mogą ulec zmianie w każdej wersji. Aby wyświetlić wszystkie strony w RCL, zajrzyj do źródła referencyjnego ASP.NET Core (dotnet/aspnetcore repozytorium GitHub, Identity/UI/src/Areas/Identity/Pages folder). Poszczególne strony lub wszystkie strony można skleić w aplikacji. Aby uzyskać więcej informacji, zobacz Szkielet Identity w projektach ASP.NET Core.

Tworzenie aplikacji MVC z uwierzytelnianiem

Utwórz projekt ASP.NET Core MVC przy użyciu kont indywidualnych.

  • Wybierz szablon ASP.NET Core Web App (Model-View-Controller). Wybierz Dalej.
  • W polu Typ uwierzytelniania wybierz pozycję Indywidualne konta.
  • Wybierz Utwórz.

Wygenerowany projekt udostępnia ASP.NET Core Identity jako bibliotekęRazor klas (RCL). Biblioteka IdentityRazor klas jest oparta na Razor stronach i uwidacznia punkty końcowe w Identity obszarze. Na przykład:

  • Areas/Identity/Pages/Account/Register
  • Areas/Identity/Pages/Account/Login
  • Areas/Identity/Pages/Account/Manage/ChangePassword

Strony są opisane indywidualnie w dokumentacji dla określonych przypadków użycia i mogą ulec zmianie w każdej wersji. Aby wyświetlić wszystkie strony w RCL, zajrzyj do źródła referencyjnego ASP.NET Core (dotnet/aspnetcore repozytorium GitHub, Identity/UI/src/Areas/Identity/Pages folder). Poszczególne strony lub wszystkie strony można skleić w aplikacji. Aby uzyskać więcej informacji, zobacz Szkielet Identity w projektach ASP.NET Core.

Zastosuj migracje

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 na dbo.AspNetUsers> i wybierz Wyświetl dane:

Menu kontekstowe w tabeli AspNetUsers w programie SQL Server Eksplorator obiektów

Konfigurowanie Identity usług

Usługi są dodawane w Program.cs. Typowy wzorzec polega na wywołaniu metod w następującej kolejności:

  1. Add{Service}
  2. 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 przez wstrzykiwanie zależności.

Identity jest włączane przez wywołanie UseAuthentication. UseAuthenticationDodaje 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, UseAuthenticationi UseAuthorization musi być wywoływana w kolejności pokazanej w poprzednim kodzie.

Aby uzyskać więcej informacji na temat IdentityOptionsprogramu , zobacz IdentityOptions i Uruchamianie aplikacji.

Szkielet, logowanie, wylogowanie i potwierdzenie rejestracji

Dodaj pliki Register, Login, LogOut i RegisterConfirmation. Postępuj zgodnie z identyfikatorem szkieletu do projektu Razor z instrukcjami dotyczącymi autoryzacji, aby wygenerować kod przedstawiony 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) na obiekcie _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();
}

Wyłącz domyślną weryfikację konta

W przypadku szablonów domyślnych użytkownik jest przekierowywany do Account.RegisterConfirmation, gdzie może kliknąć 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 DisplayConfirmAccountLink = false w /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, wywoływana jest akcja OnPostAsync. PasswordSignInAsync jest wywoływane na obiekcie _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();
}

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 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ć Identity, dodaj [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 jesteś zalogowany, wyloguj się. Uruchom aplikację i wybierz łącze Privacy. Nastąpi przekierowanie do strony logowania.

Odkrywaj Identity

Aby zbadać Identity bardziej szczegółowo:

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 Identity, i jest dołączany przez Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migrowanie do platformy ASP.NET Core Identity

Aby uzyskać więcej informacji i wskazówek dotyczących migrowania istniejącego Identity sklepu, zapoznaj się z Migrowanie uwierzytelniania i Identity.

Ustawianie siły hasła

Zobacz w Konfiguracji przykład, który ustala 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 AddDefaultIdentity source.

Zablokuj publikowanie zasobów statycznych Identity

Aby zapobiec publikowaniu statycznych Identity zasobów (arkuszy stylów i plików JavaScript dla Identity interfejsu użytkownika) do katalogu głównego sieci Web, dodaj następującą ResolveStaticWebAssetsInputsDependsOn właściwość i RemoveIdentityAssets cel 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

Autor: Rick Anderson

ASP.NET Core Identity:

  • To API, które obsługuje logowanie w interfejsie 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. Twórz szkielet Identity i wyświetlaj wygenerowane pliki, aby przejrzeć interakcję szablonu z Identity.

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 używać Identity do zarejestrowania, zalogowania i wylogowania 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ązana z platformą tożsamości Microsoft. Platforma tożsamości firmy 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ć interfejsy API dla aplikacji webowych i SPA, użyj jednej z następujących opcji:

Duende Identity Server to platforma OpenID Connect 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/wylogowanie jednokrotne 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 Migrowanie z platformy ASP.NET Core na platformie .NET 5 do platformy .NET 6.

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, aby miała taką samą przestrzeń nazw jak projekt pobrany. 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ę klas Razor. Biblioteka IdentityRazor klas uwidacznia punkty końcowe w Identity obszarze. Na przykład:

  • /Identity/Konto/Logowanie
  • /Identity/Konto/Wylogowywanie
  • /Identity/Konto/Zarządzanie

Zastosuj migracje

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 na dbo.AspNetUsers> i wybierz Wyświetl dane:

Menu kontekstowe w tabeli AspNetUsers w programie SQL Server Eksplorator obiektów

Konfigurowanie Identity usług

Usługi są dodawane w Program.cs. Typowy wzorzec polega na wywołaniu metod w następującej kolejności:

  1. Add{Service}
  2. 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 przez wstrzykiwanie zależności.

Identity jest włączane przez wywołanie UseAuthentication. UseAuthenticationDodaje 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, UseAuthenticationi UseAuthorization musi być wywoływana w kolejności pokazanej w poprzednim kodzie.

Aby uzyskać więcej informacji na temat IdentityOptionsprogramu , zobacz IdentityOptions i Uruchamianie aplikacji.

Szkielet, logowanie, wylogowanie i potwierdzenie rejestracji

Dodaj pliki Register, Login, LogOut i RegisterConfirmation. Postępuj zgodnie z identyfikatorem szkieletu do projektu Razor z instrukcjami dotyczącymi autoryzacji, aby wygenerować kod przedstawiony 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) na obiekcie _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();
}

Wyłącz domyślną weryfikację konta

W przypadku szablonów domyślnych użytkownik jest przekierowywany do Account.RegisterConfirmation, gdzie może kliknąć 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 DisplayConfirmAccountLink = false w /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, wywoływana jest akcja OnPostAsync. PasswordSignInAsync jest wywoływane na obiekcie _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();
}

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 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ć Identity, dodaj [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 jesteś zalogowany, wyloguj się. Uruchom aplikację i wybierz łącze Privacy. Nastąpi przekierowanie do strony logowania.

Odkrywaj Identity

Aby zbadać Identity bardziej szczegółowo:

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 Identity, i jest dołączany przez Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migrowanie do platformy ASP.NET Core Identity

Aby uzyskać więcej informacji i wskazówek dotyczących migrowania istniejącego Identity sklepu, zapoznaj się z Migrowanie uwierzytelniania i Identity.

Ustawianie siły hasła

Zobacz w Konfiguracji przykład, który ustala 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 AddDefaultIdentity source.

Zablokuj publikowanie zasobów statycznych Identity

Aby zapobiec publikowaniu statycznych Identity zasobów (arkuszy stylów i plików JavaScript dla Identity interfejsu użytkownika) do katalogu głównego sieci Web, dodaj następującą ResolveStaticWebAssetsInputsDependsOn właściwość i RemoveIdentityAssets cel 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

Autor: Rick Anderson

ASP.NET Core Identity:

  • To API, które obsługuje logowanie w interfejsie 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. Twórz szkielet Identity i wyświetlaj wygenerowane pliki, aby przejrzeć interakcję szablonu z Identity.

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 używać Identity do zarejestrowania, zalogowania i wylogowania 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 firmy 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ć interfejsy API dla aplikacji webowych i SPA, użyj jednej z następujących opcji:

Duende IdentityServer to platforma OpenID Connect i OAuth 2.0 dla ASP.NET Core. Serwer Duende IdentityServer umożliwia korzystanie z następujących funkcji zabezpieczeń:

  • Uwierzytelnianie jako usługa (AaaS)
  • Logowanie jednokrotne/wylogowanie jednokrotne w wielu typach aplikacji
  • Kontrola dostępu dla interfejsów API
  • Brama federacyjna

Aby uzyskać więcej informacji, zobacz Omówienie Duende IdentityServer.

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 Plik>Nowy>Projekt.
  • Wybierz pozycję ASP.NET Core Web Application(Podstawowa aplikacja internetowa). Nadaj projektowi nazwę WebApp1, aby miała taką samą przestrzeń nazw jak projekt pobrany. 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ę klas Razor. Biblioteka IdentityRazor klas uwidacznia punkty końcowe w Identity obszarze. Na przykład:

  • /Identity/Konto/Logowanie
  • /Identity/Konto/Wylogowywanie
  • /Identity/Konto/Zarządzanie

Zastosuj migracje

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 na dbo.AspNetUsers> i wybierz Wyświetl dane:

Menu kontekstowe w tabeli AspNetUsers w programie SQL Server Eksplorator obiektów

Konfigurowanie Identity usług

Usługi są dodawane w 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 przez wstrzykiwanie zależności.

Identity jest włączane przez wywołanie UseAuthentication. UseAuthenticationDodaje 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 przez wstrzykiwanie zależności.

Identity jest włączane przez wywołanie UseAuthentication. UseAuthenticationDodaje 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 muszą być wywoływane w kolejności pokazanej w poprzednim kodzie.

Aby uzyskać więcej informacji na temat IdentityOptions i Startup, zobacz IdentityOptions i Application Startup (Uruchamianie aplikacji).

Szkielet, logowanie, wylogowanie i potwierdzenie rejestracji

Dodaj pliki Register, Login, LogOut i RegisterConfirmation. Postępuj zgodnie z identyfikatorem szkieletu do projektu Razor z instrukcjami dotyczącymi autoryzacji, aby wygenerować kod przedstawiony 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) na obiekcie _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();
}

Wyłącz domyślną weryfikację konta

W przypadku szablonów domyślnych użytkownik jest przekierowywany do Account.RegisterConfirmation, gdzie może kliknąć 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 DisplayConfirmAccountLink = false w /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, wywoływana jest akcja OnPostAsync. PasswordSignInAsync jest wywoływane na obiekcie _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();
}

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 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ć Identity, dodaj [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 jesteś zalogowany, wyloguj się. Uruchom aplikację i wybierz łącze Privacy. Nastąpi przekierowanie do strony logowania.

Odkrywaj Identity

Aby zbadać Identity bardziej szczegółowo:

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 Identity, i jest dołączany przez Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Migrowanie do platformy ASP.NET Core Identity

Aby uzyskać więcej informacji i wskazówek dotyczących migrowania istniejącego Identity sklepu, zapoznaj się z Migrowanie uwierzytelniania i Identity.

Ustawianie siły hasła

Zobacz w Konfiguracji przykład, który ustala minimalne wymagania dotyczące hasła.

Zablokuj publikowanie zasobów statycznych Identity

Aby zapobiec publikowaniu statycznych Identity zasobów (arkuszy stylów i plików JavaScript dla Identity interfejsu użytkownika) do katalogu głównego sieci Web, dodaj następującą ResolveStaticWebAssetsInputsDependsOn właściwość i RemoveIdentityAssets cel 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