Úvod do Identity ASP.NET Core

Autor: Rick Anderson

ASP.NET Core Identity:

  • Je rozhraní API, které podporuje funkce přihlášení uživatelského rozhraní.
  • Spravuje uživatele, hesla, profilová data, role, deklarace identity, tokeny, potvrzení e-mailu a další.

Uživatelé mohou vytvořit účet s přihlašovacími informacemi uloženými v nebo Identity mohou použít externího zprostředkovatele přihlášení. Mezi podporované externí zprostředkovatele přihlašování patří Facebook, Google, účet Microsofta Twitter .

Informace o tom, jak globálně vyžadovat ověření všech uživatelů, najdete v tématu vyžadování ověřených uživatelů.

Zdrojový Identity kód je k dispozici na GitHub. Generování uživatelského Identity rozhraní a zobrazit vygenerované soubory a zkontrolovat interakci šablony s Identity .

Identityse obvykle konfiguruje pomocí SQL Server databáze pro ukládání uživatelských jmen, hesel a dat profilu. Další možností je použít jiné trvalé úložiště, například Azure Table Storage.

V tomto tématu se dozvíte, jak použít Identity k registraci, přihlášení a odhlášení uživatele. Poznámka: Šablony zachází s uživatelským jménem a e-mailem stejně pro uživatele. Podrobnější pokyny k vytváření aplikací, které používají , najdete Identity v části Další kroky.

Microsoft identity platform je:

  • Vývoj vývojové platformy Azure Active Directory (Azure AD).
  • Nesouvisí s ASP.NET Core Identity .

ASP.NET Core Identitypřidá funkci přihlášení uživatelského rozhraní (UI) k ASP.NET Core web apps. K zabezpečení webových rozhraní API a jednostránkové použijte jednu z následujících možností:

IdentityServer4 je OpenID Připojení a OAuth 2,0 framework pro ASP.NET Core. IdentityServer4 umožňuje následující funkce zabezpečení:

  • Ověřování jako služba (AaaS)
  • Jednotné přihlašování/vypínání (SSO) nad více typy aplikací
  • Řízení přístupu pro rozhraní API
  • Federační brána

Další informace najdete v tématu Vítá vás Identity Server4.

Zobrazení nebo stažení ukázkového kódu (stažení ).

Vytvoření webové aplikace s ověřováním

Vytvořte projekt webové ASP.NET Core aplikace s individuálními uživatelskými účty.

  • Vyberte šablonu ASP.NET Core webovou aplikaci. Pojmechte projekt WebApp1 tak, aby měl stejný obor názvů jako projekt ke stažení. Klikněte na OK.
  • Ve vstupu Typ ověřování vyberte Jednotlivé uživatelské účty.

Vygenerovaný projekt poskytuje ASP.NET Core Identity jako Razor knihovnu tříd. Knihovna Identity Razor tříd zpřístupňuje koncové body s Identity oblastí . Například:

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Manage

Použití migrací

Použijte migrace k inicializaci databáze.

V konzole pro správu Správce balíčků (PMC) spusťte následující příkaz:

Update-Database

Testovací registrace a přihlášení

Spusťte aplikaci a zaregistrujte uživatele. V závislosti na velikosti obrazovky možná budete muset vybrat navigační přepínací tlačítko, abyste viděli odkazy registrovat a přihlásit se.

Zobrazení Identity databáze

  • V nabídce zobrazení vyberte možnost Průzkumník objektů systému SQL Server (SSOX).
  • Přejděte na (LocalDB) MSSQLLocalDB (SQL Server 13). Klikněte pravým tlačítkem na dbo. AspNetUsers > zobrazení dat:

Kontextová nabídka v tabulce AspNetUsers v Průzkumník objektů systému SQL Server

Konfigurace Identity služeb

Služby se přidávají v souboru Program.cs. Typickým vzorem je volání metod v následujícím pořadí:

  1. Add{Service}
  2. Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;

var builder = WebApplication.CreateBuilder(args);

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();

builder.Services.Configure<IdentityOptions>(options =>
{
    // Password settings.
    options.Password.RequireDigit = true;
    options.Password.RequireLowercase = true;
    options.Password.RequireNonAlphanumeric = true;
    options.Password.RequireUppercase = true;
    options.Password.RequiredLength = 6;
    options.Password.RequiredUniqueChars = 1;

    // Lockout settings.
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;

    // User settings.
    options.User.AllowedUserNameCharacters =
    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
    options.User.RequireUniqueEmail = false;
});

builder.Services.ConfigureApplicationCookie(options =>
{
    // Cookie settings
    options.Cookie.HttpOnly = true;
    options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

    options.LoginPath = "/Identity/Account/Login";
    options.AccessDeniedPath = "/Identity/Account/AccessDenied";
    options.SlidingExpiration = true;
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();

app.Run();

Předchozí kód nakonfiguruje výchozí Identity hodnoty možností. Služby jsou pro aplikaci dostupné prostřednictvím injektáže závislostí.

Identity je povolen voláním useAuthentication. UseAuthenticationpřidá do kanálu požadavku ověřovací middleware.

Aplikace vygenerovaná šablonou nepou3/4í autorizaci. app.UseAuthorization se zahrne, aby se zajistilo, že se přidá ve správném pořadí v případě, že aplikace přidá autorizaci. UseRouting, UseAuthentication UseAuthorization , a musí být UseEndpoints volány v pořadí zobrazeném v předchozím kódu.

Další informace o nástroji IdentityOptions najdete v tématu a Spuštění IdentityOptions aplikace.

Scaffold Register, Login, LogOut a RegisterConfirmation

Přidejte Register soubory , , a Login LogOut RegisterConfirmation . Postupujte podle identity generování uživatelského rozhraní do projektu s Razor pokyny k autorizaci a vygenerování kódu zobrazeného v této části.

Prozkoumání registru

Když uživatel na stránce klikne na tlačítko Zaregistrovat, Register vyvolá se RegisterModel.OnPostAsync akce. Uživatel je vytvořen pomocí CreateAsync pro _userManager objekt :

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Zakázat ověřování výchozího účtu

S výchozími šablonami se uživatel přesměruje na Account.RegisterConfirmation místo, kde může vybrat odkaz pro potvrzení účtu. Ve výchozím nastavení Account.RegisterConfirmation se používá jenom pro testování. v produkční aplikaci by se mělo zakázat automatické ověření účtu.

Pokud chcete vyžadovat potvrzující účet a zabránit okamžitému přihlášení při registraci, nastavte DisplayConfirmAccountLink = false v /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();
    }
}

Přihlášení

Formulář Přihlášení se zobrazí v případě, že:

  • Je vybraný odkaz Přihlásit se.
  • Uživatel se pokusí získat přístup ke stránce s omezeným přístupem, ke které není autorizovaný nebo pokud nebyl ověřen systémem.

Když se formulář na přihlašovací stránce odeslal, OnPostAsync volá se akce. PasswordSignInAsync se volá u _signInManager objektu .

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Informace o rozhodování o autorizaci najdete v tématu Úvod do autorizace v ASP.NET Core .

Odhlásit se

Akci vyvolá odkaz LogoutModel.OnPost Odhlásit se.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

V předchozím kódu musí být kód přesměrováním, aby prohlížeč provede nový požadavek a aby se aktualizovala identita return RedirectToPage(); uživatele.

SignOutAsync vymaže deklarace identity uživatele uložené v cookie .

Post se zadá v souboru Pages/Shared/_LoginPartial.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Test Identity

Výchozí šablony webového projektu umožňují anonymní přístup k domovských stránkám. Pokud chcete Identity testovat, přidejte [Authorize] :

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Pokud jste přihlášení, odhlásit se. Spusťte aplikaci a vyberte Privacy odkaz. Budete přesměrováni na přihlašovací stránku.

Prozkoumat Identity

Podrobnější Identity zkoumání:

Identity Součásti

Všechny Identity balíčky -dependent NuGet jsou součástí sdílené architektury ASP.NET Core .

Primární balíček pro je Identity Microsoft.AspNetCore. Identity . Tento balíček obsahuje základní sadu rozhraní pro ASP.NET Core Identity a je součástí Microsoft.AspNetCore.Identity.EntityFrameworkCore .

Migrace na ASP.NET Core Identity

Další informace a pokyny k migraci stávajícího úložiště najdete v Identity tématu Migrace Identity ověřování a .

Nastavení síly hesla

Ukázku, která nastavuje minimální požadavky na heslo, najdete v části Konfigurace.

AddDefault Identity a AddIdentity

AddDefaultIdentitybyl představen ve ASP.NET Core 2.1. Volání AddDefaultIdentity se podobá následujícímu volání:

Další informace najdete v tématu Identity PřidáníVýchozí zdroj.

Zabránění publikování Identity statických prostředků

Pokud chcete zabránit publikování statických prostředků (šablony stylů a soubory JavaScriptu pro uživatelské rozhraní) do kořenového adresáře webu, přidejte do souboru projektu aplikace následující vlastnost a Identity Identity ResolveStaticWebAssetsInputsDependsOn RemoveIdentityAssets cíl:

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Další kroky

Autor: Rick Anderson

ASP.NET Core Identity:

  • Je rozhraní API, které podporuje funkce přihlášení uživatelského rozhraní.
  • Spravuje uživatele, hesla, profilová data, role, deklarace identity, tokeny, potvrzení e-mailu a další.

Uživatelé mohou vytvořit účet s přihlašovacími informacemi uloženými v nebo Identity mohou použít externího zprostředkovatele přihlášení. Mezi podporované externí zprostředkovatele přihlašování patří Facebook, Google, účet Microsofta Twitter .

Informace o tom, jak globálně vyžadovat ověření všech uživatelů, najdete v tématu vyžadování ověřených uživatelů.

Zdrojový Identity kód je k dispozici na GitHub. Generování uživatelského Identity rozhraní a zobrazit vygenerované soubory a zkontrolovat interakci šablony s Identity .

Identityse obvykle konfiguruje pomocí SQL Server k ukládání uživatelských jmen, hesel a dat profilu. Další možností je použít jiné trvalé úložiště, například Azure Table Storage.

V tomto tématu se dozvíte, jak použít Identity k registraci, přihlášení a odhlášení uživatele. Poznámka: Šablony zachází s uživatelským jménem a e-mailem stejně pro uživatele. Podrobnější pokyny k vytváření aplikací, které používají , najdete Identity v části Další kroky.

Microsoft identity platform je:

  • Vývoj vývojové platformy Azure Active Directory (Azure AD).
  • Nesouvisí s ASP.NET Core Identity .

ASP.NET Core Identitypřidá funkci přihlášení uživatelského rozhraní (UI) k ASP.NET Core web apps. K zabezpečení webových rozhraní API a jednostránkové použijte jednu z následujících možností:

IdentityServer4 je OpenID Připojení a OAuth 2,0 framework pro ASP.NET Core. IdentityServer4 umožňuje následující funkce zabezpečení:

  • Ověřování jako služba (AaaS)
  • Jednotné přihlašování/vypínání (SSO) nad více typy aplikací
  • Řízení přístupu pro rozhraní API
  • Federační brána

Další informace najdete v tématu Vítá vás Identity Server4.

Zobrazení nebo stažení ukázkového kódu (stažení ).

Vytvoření webové aplikace s ověřováním

Vytvořte projekt webové ASP.NET Core aplikace s individuálními uživatelskými účty.

  • Vyberte Soubor > Nový > Project.
  • Vyberte ASP.NET Core Web Application (Webová aplikace). Pojmechte projekt WebApp1 tak, aby měl stejný obor názvů jako projekt ke stažení. Klikněte na OK.
  • Vyberte aplikaci ASP.NET Core a pak vyberte Změnit ověřování.
  • Vyberte Jednotlivé uživatelské účty a klikněte na OK.

Vygenerovaný projekt poskytuje ASP.NET Core Identity jako Razor knihovnu tříd. Knihovna Identity Razor tříd zpřístupňuje koncové body s Identity oblastí . Například:

  • /Identity/Account/Login
  • /Identity/Account/Logout
  • /Identity/Account/Manage

Použití migrací

Použijte migrace k inicializaci databáze.

V konzole pro správu Správce balíčků (PMC) spusťte následující příkaz:

PM> Update-Database

Testovací registrace a přihlášení

Spusťte aplikaci a zaregistrujte uživatele. V závislosti na velikosti obrazovky možná budete muset vybrat navigační přepínací tlačítko, abyste viděli odkazy registrovat a přihlásit se.

Zobrazení Identity databáze

  • V nabídce zobrazení vyberte možnost Průzkumník objektů systému SQL Server (SSOX).
  • Přejděte na (LocalDB) MSSQLLocalDB (SQL Server 13). Klikněte pravým tlačítkem na dbo. AspNetUsers > zobrazení dat:

Kontextová nabídka v tabulce AspNetUsers v Průzkumník objektů systému SQL Server

Konfigurace Identity služeb

Služby se přidávají v ConfigureServices . Typickým vzorem je volání všech metod a Add{Service} potom volání všech 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;
    });
}

Předchozí zvýrazněný kód nakonfiguruje Identity výchozí hodnoty možností. Služby jsou pro aplikaci dostupné prostřednictvím injektáže závislostí.

Identity je povolený voláním UseAuthentication . UseAuthenticationpřidá do kanálu požadavku ověřovací middleware.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        // options.UseSqlite(
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDatabaseDeveloperPageExceptionFilter();
    services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();
    services.AddRazorPages();

    services.Configure<IdentityOptions>(options =>
    {
        // Password settings.
        options.Password.RequireDigit = true;
        options.Password.RequireLowercase = true;
        options.Password.RequireNonAlphanumeric = true;
        options.Password.RequireUppercase = true;
        options.Password.RequiredLength = 6;
        options.Password.RequiredUniqueChars = 1;

        // Lockout settings.
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // User settings.
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie settings
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Identity/Account/Login";
        options.AccessDeniedPath = "/Identity/Account/AccessDenied";
        options.SlidingExpiration = true;
    });
}

Předchozí kód nakonfiguruje výchozí Identity hodnoty možností. Služby jsou pro aplikaci dostupné prostřednictvím injektáže závislostí.

Identity je povolen voláním useAuthentication. UseAuthenticationpřidá do kanálu požadavku ověřovací middleware.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseMigrationsEndPoint();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Aplikace vygenerovaná šablonou nepou3/4í autorizaci. app.UseAuthorization se zahrne, aby se zajistilo, že se přidá ve správném pořadí v případě, že aplikace přidá autorizaci. UseRouting, UseAuthentication UseAuthorization , a musí být UseEndpoints volány v pořadí zobrazeném v předchozím kódu.

Další informace o a najdete IdentityOptions v tématu a Spuštění Startup IdentityOptions aplikace.

Scaffold Register, Login, LogOut a RegisterConfirmation

Přidejte Register soubory , , a Login LogOut RegisterConfirmation . Postupujte podle identity generování uživatelského rozhraní do projektu s Razor pokyny k autorizaci a vygenerování kódu zobrazeného v této části.

Prozkoumání registru

Když uživatel na stránce klikne na tlačítko Zaregistrovat, Register vyvolá se RegisterModel.OnPostAsync akce. Uživatel je vytvořen pomocí CreateAsync pro _userManager objekt :

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync())
                                          .ToList();
    if (ModelState.IsValid)
    {
        var user = new IdentityUser { UserName = Input.Email, Email = Input.Email };
        var result = await _userManager.CreateAsync(user, Input.Password);
        if (result.Succeeded)
        {
            _logger.LogInformation("User created a new account with password.");

            var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
            code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { area = "Identity", userId = user.Id, code = code },
                protocol: Request.Scheme);

            await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
                $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");

            if (_userManager.Options.SignIn.RequireConfirmedAccount)
            {
                return RedirectToPage("RegisterConfirmation", 
                                      new { email = Input.Email });
            }
            else
            {
                await _signInManager.SignInAsync(user, isPersistent: false);
                return LocalRedirect(returnUrl);
            }
        }
        foreach (var error in result.Errors)
        {
            ModelState.AddModelError(string.Empty, error.Description);
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Zakázat ověřování výchozího účtu

S výchozími šablonami se uživatel přesměruje na Account.RegisterConfirmation místo, kde může vybrat odkaz pro potvrzení účtu. Ve výchozím nastavení Account.RegisterConfirmation se používá jenom pro testování. v produkční aplikaci by se mělo zakázat automatické ověření účtu.

Pokud chcete vyžadovat potvrzující účet a zabránit okamžitému přihlášení při registraci, nastavte DisplayConfirmAccountLink = false v /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();
    }
}

Přihlášení

Formulář Přihlášení se zobrazí v případě, že:

  • Je vybraný odkaz Přihlásit se.
  • Uživatel se pokusí získat přístup ke stránce s omezeným přístupem, ke které není autorizovaný nebo pokud nebyl ověřen systémem.

Když se formulář na přihlašovací stránce odeslal, OnPostAsync volá se akce. PasswordSignInAsync se volá u _signInManager objektu .

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");

    if (ModelState.IsValid)
    {
        // This doesn't count login failures towards account lockout
        // To enable password failures to trigger account lockout, 
        // set lockoutOnFailure: true
        var result = await _signInManager.PasswordSignInAsync(Input.Email,
                           Input.Password, Input.RememberMe, lockoutOnFailure: true);
        if (result.Succeeded)
        {
            _logger.LogInformation("User logged in.");
            return LocalRedirect(returnUrl);
        }
        if (result.RequiresTwoFactor)
        {
            return RedirectToPage("./LoginWith2fa", new
            {
                ReturnUrl = returnUrl,
                RememberMe = Input.RememberMe
            });
        }
        if (result.IsLockedOut)
        {
            _logger.LogWarning("User account locked out.");
            return RedirectToPage("./Lockout");
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

Informace o rozhodování o autorizaci najdete v tématu Úvod do autorizace v ASP.NET Core .

Odhlásit se

Akci vyvolá odkaz LogoutModel.OnPost Odhlásit se.

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;

namespace WebApp1.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LogoutModel : PageModel
    {
        private readonly SignInManager<IdentityUser> _signInManager;
        private readonly ILogger<LogoutModel> _logger;

        public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
        {
            _signInManager = signInManager;
            _logger = logger;
        }

        public void OnGet()
        {
        }

        public async Task<IActionResult> OnPost(string returnUrl = null)
        {
            await _signInManager.SignOutAsync();
            _logger.LogInformation("User logged out.");
            if (returnUrl != null)
            {
                return LocalRedirect(returnUrl);
            }
            else
            {
                return RedirectToPage();
            }
        }
    }
}

V předchozím kódu musí být kód přesměrováním, aby prohlížeč provede nový požadavek a aby se aktualizovala identita return RedirectToPage(); uživatele.

SignOutAsync vymaže deklarace identity uživatele uložené v cookie .

Post se zadá v souboru Pages/Shared/_LoginPartial.cshtml:

@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager

<ul class="navbar-nav">
@if (SignInManager.IsSignedIn(User))
{
    <li class="nav-item">
        <a  class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" 
                                              title="Manage">Hello @User.Identity.Name!</a>
    </li>
    <li class="nav-item">
        <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" 
                                  asp-route-returnUrl="@Url.Page("/", new { area = "" })" 
                                  method="post" >
            <button  type="submit" class="nav-link btn btn-link text-dark">Logout</button>
        </form>
    </li>
}
else
{
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a>
    </li>
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
}
</ul>

Test Identity

Výchozí šablony webového projektu umožňují anonymní přístup k domovských stránkám. Pokud chcete Identity testovat, přidejte [Authorize] :

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        private readonly ILogger<PrivacyModel> _logger;

        public PrivacyModel(ILogger<PrivacyModel> logger)
        {
            _logger = logger;
        }

        public void OnGet()
        {
        }
    }
}

Pokud jste přihlášení, odhlásit se. Spusťte aplikaci a vyberte Privacy odkaz. Budete přesměrováni na přihlašovací stránku.

Prozkoumat Identity

Podrobnější Identity zkoumání:

Identity Součásti

Všechny Identity balíčky -dependent NuGet jsou součástí sdílené architektury ASP.NET Core .

Primární balíček pro je Identity Microsoft.AspNetCore. Identity . Tento balíček obsahuje základní sadu rozhraní pro ASP.NET Core Identity a je součástí Microsoft.AspNetCore.Identity.EntityFrameworkCore .

Migrace na ASP.NET Core Identity

Další informace a pokyny k migraci stávajícího úložiště najdete v Identity tématu Migrace Identity ověřování a .

Nastavení síly hesla

Ukázku, která nastavuje minimální požadavky na heslo, najdete v části Konfigurace.

AddDefault Identity a AddIdentity

AddDefaultIdentitybyl představen ve ASP.NET Core 2.1. Volání AddDefaultIdentity se podobá následujícímu volání:

Další informace najdete v tématu Identity PřidáníVýchozí zdroj.

Zabránění publikování Identity statických prostředků

Pokud chcete zabránit publikování statických prostředků (šablony stylů a soubory JavaScriptu pro uživatelské rozhraní) do kořenového adresáře webu, přidejte do souboru projektu aplikace následující vlastnost a Identity Identity ResolveStaticWebAssetsInputsDependsOn RemoveIdentityAssets cíl:

<PropertyGroup>
  <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>

<Target Name="RemoveIdentityAssets">
  <ItemGroup>
    <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
  </ItemGroup>
</Target>

Další kroky