ASP.NET Core 上的身分識別簡介Introduction to Identity on ASP.NET Core

Rick Anderson 提供By Rick Anderson

ASP.NET Core 身分識別是支援使用者介面(UI)登入功能的成員資格系統。ASP.NET Core Identity is a membership system that supports user interface (UI) login functionality. 使用者可以建立帳戶,其中包含儲存在身分識別中的登入資訊,或可以使用外部登入提供者。Users can create an account with the login information stored in Identity or they can use an external login provider. 支援的外部登入提供者包括Facebook、Google、Microsoft 帳戶及 TwitterSupported external login providers include Facebook, Google, Microsoft Account, and Twitter.

您可以使用 SQL Server 資料庫來設定身分識別,以儲存使用者名稱、密碼和設定檔資料。Identity can be configured using a SQL Server database to store user names, passwords, and profile data. 或者,也可以使用另一個持續性存放區,例如 Azure 表格儲存體。Alternatively, another persistent store can be used, for example, Azure Table Storage.

在本主題中,您將瞭解如何使用身分識別來註冊、登入和登出使用者。In this topic, you learn how to use Identity to register, log in, and log out a user. 如需有關建立使用身分識別之應用程式的詳細指示,請參閱本文結尾的後續步驟一節。For more detailed instructions about creating apps that use Identity, see the Next Steps section at the end of this article.

ASP.NET Core 身分識別會將使用者介面(UI)登入功能新增至 ASP.NET Core web 應用程式。ASP.NET Core Identity adds user interface (UI) login functionality to ASP.NET Core web apps. 若要保護 web Api 和 Spa,請使用下列其中一項:To secure web APIs and SPAs, use one of the following:

IdentityServer4 是適用于 ASP.NET Core 3.0 的 OpenID Connect 和 OAuth 2.0 架構。IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core 3.0. IdentityServer4 可啟用下列安全性功能:IdentityServer4 enables the following security features:

  • 驗證即服務(AaaS)Authentication as a Service (AaaS)
  • 多個應用程式類型的單一登入/關閉(SSO)Single sign-on/off (SSO) over multiple application types
  • Api 的存取控制Access control for APIs
  • 同盟閘道Federation Gateway

如需詳細資訊,請參閱歡迎使用 IdentityServer4For more information, see Welcome to IdentityServer4.

查看或下載範例程式碼如何下載))。View or download the sample code (how to download)).

建立具有驗證的 Web 應用程式Create a Web app with authentication

建立具有個別使用者帳戶的 ASP.NET Core Web 應用程式專案。Create an ASP.NET Core Web Application project with Individual User Accounts.

  • 選取 [ 檔案] > [新增>專案]。Select File > New > Project.
  • 選取 [ASP.NET Core Web 應用程式]。Select ASP.NET Core Web Application. 將專案命名為WebApp1 ,使其命名空間與專案下載相同。Name the project WebApp1 to have the same namespace as the project download. 按一下 [確定]。Click OK.
  • 選取 ASP.NET Core Web 應用程式,然後選取 [變更驗證]。Select an ASP.NET Core Web Application, then select Change Authentication.
  • 選取 [個別使用者帳戶],然後按一下 [確定]Select Individual User Accounts and click OK.

產生的專案會提供ASP.NET Core 身分識別做為Razor 類別庫The generated project provides ASP.NET Core Identity as a Razor Class Library. 身分識別 Razor 類別庫會公開具有 Identity 區域的端點。The Identity Razor Class Library exposes endpoints with the Identity area. 例如:For example:

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

套用移轉Apply migrations

套用遷移來初始化資料庫。Apply the migrations to initialize the database.

在 [套件管理員主控台] (PMC)中執行下列命令:Run the following command in the Package Manager Console (PMC):

PM> Update-Database

測試註冊和登入Test Register and Login

執行應用程式並註冊使用者。Run the app and register a user. 視您的螢幕大小而定,您可能需要選取 [流覽] 切換按鈕,才能看到 [註冊] 和 [登入] 連結。Depending on your screen size, you might need to select the navigation toggle button to see the Register and Login links.

檢視識別資料庫View the Identity database

  • 檢視功能表上,選取SQL Server 物件總管(SSOX)。From the View menu, select SQL Server Object Explorer (SSOX).
  • 瀏覽至 (localdb) (SQL Server 13) MSSQLLocalDBNavigate to (localdb)MSSQLLocalDB(SQL Server 13). 以滑鼠右鍵按一下dbo。AspNetUsers > 檢視資料:Right-click on dbo.AspNetUsers > View Data:

SQL Server 物件總管 中的 AspNetUsers 資料表上的操作功能表

設定身分識別服務Configure Identity services

服務會在 ConfigureServices 中新增。Services are added in ConfigureServices. 典型模式是呼叫所有 Add{Service} 方法,然後呼叫 services.Configure{Service} 方法。The typical pattern is to call all the Add{Service} methods, and then call all the services.Configure{Service} methods.

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ApplicationDbContext>(options =>
        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;
    });
}

上述的反白顯示程式碼會使用預設選項值來設定身分識別。The preceding highlighted code configures Identity with default option values. 服務可透過相依性插入提供給應用程式。Services are made available to the app through dependency injection.

識別是藉由呼叫 UseAuthentication 來啟用。Identity is enabled by calling UseAuthentication. UseAuthentication 會將驗證中介軟體新增至要求管線。UseAuthentication adds authentication middleware to the request pipeline.

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();
    });
}

範本產生的應用程式不會使用授權The template-generated app doesn't use authorization. 包含 app.UseAuthorization,以確保在應用程式新增授權時,會以正確的順序加入。app.UseAuthorization is included to ensure it's added in the correct order should the app add authorization. UseRoutingUseAuthenticationUseAuthorizationUseEndpoints 必須以上述程式碼中所示的順序來呼叫。UseRouting, UseAuthentication, UseAuthorization, and UseEndpoints must be called in the order shown in the preceding code.

如需 IdentityOptionsStartup 的詳細資訊,請參閱 IdentityOptions應用程式啟動For more information on IdentityOptions and Startup, see IdentityOptions and Application Startup.

Scaffold 註冊、登入和登出Scaffold Register, Login, and LogOut

新增註冊、登入和登出檔案。Add the Register, Login, and LogOut files. Scaffold 身分識別遵循具有授權指示的 Razor 專案,以產生本節所示的程式碼。Follow the Scaffold identity into a Razor project with authorization instructions to generate the code shown in this section.

檢查 RegisterExamine Register

當使用者按一下 [註冊] 連結時,就會叫用 RegisterModel.OnPostAsync 動作。When a user clicks the Register link, the RegisterModel.OnPostAsync action is invoked. 使用者是透過CreateAsync_userManager 物件上建立的。The user is created by CreateAsync on the _userManager object. _userManager 是由相依性插入所提供):_userManager is provided by dependency injection):

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();
}

如果成功建立使用者,則會透過呼叫 _signInManager.SignInAsync 來登入使用者。If the user was created successfully, the user is logged in by the call to _signInManager.SignInAsync.

請參閱帳戶確認以取得在註冊時防止立即登入的步驟。See account confirmation for steps to prevent immediate login at registration.

登錄Log in

登入表單的顯示時機如下:The Login form is displayed when:

  • 已選取 [登入] 連結。The Log in link is selected.
  • 使用者嘗試存取未獲授權存取的受限制頁面,其未經過系統驗證的情況。A user attempts to access a restricted page that they aren't authorized to access or when they haven't been authenticated by the system.

當登入頁面上的表單提交時,會呼叫 OnPostAsync 動作。When the form on the Login page is submitted, the OnPostAsync action is called. PasswordSignInAsync 是在 _signInManager 物件上呼叫(由相依性插入所提供)。PasswordSignInAsync is called on the _signInManager object (provided by dependency injection).

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();
}

基底 Controller 類別會公開可從控制器方法存取的 User 屬性。The base Controller class exposes a User property that can be accessed from controller methods. 例如,您可以列舉 User.Claims 並做出授權決策。For instance, you can enumerate User.Claims and make authorization decisions. 如需詳細資訊,請參閱介紹 ASP.NET Core 的授權For more information, see 介紹 ASP.NET Core 的授權.

登出Log out

[登出] 連結會叫用 LogoutModel.OnPost 動作。The Log out link invokes the LogoutModel.OnPost action.

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();
            }
        }
    }
}

在上述程式碼中,程式碼 return RedirectToPage(); 必須是重新導向,才能讓瀏覽器執行新的要求,並更新使用者的身分識別。In the preceding code, the code return RedirectToPage(); needs to be a redirect so that the browser performs a new request and the identity for the user gets updated.

SignOutAsync會清除儲存在 cookie 中的使用者宣告。SignOutAsync clears the user's claims stored in a cookie.

Post 是在Pages/Shared/_LoginPartial中指定的:Post is specified in the 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

預設的 Web 專案範本允許匿名存取首頁。The default web project templates allow anonymous access to the home pages. 若要測試身分識別,請新增[Authorize]To test Identity, add [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()
        {
        }
    }
}

如果您已登入,請登出。執行應用程式並選取 [隱私權] 連結。If you are signed in, sign out. Run the app and select the Privacy link. 系統會將您重新導向至登入頁面。You are redirected to the login page.

探索身分識別Explore Identity

若要更詳細地探索身分識別:To explore Identity in more detail:

身分識別元件Identity Components

所有與身分識別相關的 NuGet 套件都包含在ASP.NET Core 共用架構中。All the Identity-dependent NuGet packages are included in the ASP.NET Core shared framework.

身分識別的主要套件是AspNetCore。The primary package for Identity is Microsoft.AspNetCore.Identity. 此套件包含 ASP.NET Core 身分識別的核心介面集,而且是由 Microsoft.AspNetCore.Identity.EntityFrameworkCore 所包含。This package contains the core set of interfaces for ASP.NET Core Identity, and is included by Microsoft.AspNetCore.Identity.EntityFrameworkCore.

遷移至 ASP.NET Core 身分識別Migrating to ASP.NET Core Identity

如需有關遷移現有身分識別存放區的詳細資訊和指引,請參閱遷移驗證和身分識別For more information and guidance on migrating your existing Identity store, see Migrate Authentication and Identity.

設定密碼強度Setting password strength

如需設定最小密碼需求的範例,請參閱設定。See Configuration for a sample that sets the minimum password requirements.

AddDefaultIdentity 和 AddIdentityAddDefaultIdentity and AddIdentity

AddDefaultIdentity 是在 ASP.NET Core 2.1 中引進。AddDefaultIdentity was introduced in ASP.NET Core 2.1. 呼叫 AddDefaultIdentity 類似于呼叫下列各項:Calling AddDefaultIdentity is similar to calling the following:

如需詳細資訊,請參閱AddDefaultIdentity sourceSee AddDefaultIdentity source for more information.

後續步驟Next Steps

Rick Anderson 提供By Rick Anderson

ASP.NET Core 身分識別是將登入功能新增至 ASP.NET Core 應用程式的成員資格系統。ASP.NET Core Identity is a membership system that adds login functionality to ASP.NET Core apps. 使用者可以建立帳戶,其中包含儲存在身分識別中的登入資訊,或可以使用外部登入提供者。Users can create an account with the login information stored in Identity or they can use an external login provider. 支援的外部登入提供者包括Facebook、Google、Microsoft 帳戶及 TwitterSupported external login providers include Facebook, Google, Microsoft Account, and Twitter.

您可以使用 SQL Server 資料庫來設定身分識別,以儲存使用者名稱、密碼和設定檔資料。Identity can be configured using a SQL Server database to store user names, passwords, and profile data. 或者,也可以使用另一個持續性存放區,例如 Azure 表格儲存體。Alternatively, another persistent store can be used, for example, Azure Table Storage.

查看或下載範例程式碼如何下載))。View or download the sample code (how to download)).

在本主題中,您將瞭解如何使用身分識別來註冊、登入和登出使用者。In this topic, you learn how to use Identity to register, log in, and log out a user. 如需有關建立使用身分識別之應用程式的詳細指示,請參閱本文結尾的後續步驟一節。For more detailed instructions about creating apps that use Identity, see the Next Steps section at the end of this article.

AddDefaultIdentity 和 AddIdentityAddDefaultIdentity and AddIdentity

AddDefaultIdentity 是在 ASP.NET Core 2.1 中引進。AddDefaultIdentity was introduced in ASP.NET Core 2.1. 呼叫 AddDefaultIdentity 類似于呼叫下列各項:Calling AddDefaultIdentity is similar to calling the following:

如需詳細資訊,請參閱AddDefaultIdentity sourceSee AddDefaultIdentity source for more information.

建立具有驗證的 Web 應用程式Create a Web app with authentication

建立具有個別使用者帳戶的 ASP.NET Core Web 應用程式專案。Create an ASP.NET Core Web Application project with Individual User Accounts.

  • 選取 [ 檔案] > [新增>專案]。Select File > New > Project.
  • 選取 [ASP.NET Core Web 應用程式]。Select ASP.NET Core Web Application. 將專案命名為WebApp1 ,使其命名空間與專案下載相同。Name the project WebApp1 to have the same namespace as the project download. 按一下 [確定]。Click OK.
  • 選取 ASP.NET Core Web 應用程式,然後選取 [變更驗證]。Select an ASP.NET Core Web Application, then select Change Authentication.
  • 選取 [個別使用者帳戶],然後按一下 [確定]Select Individual User Accounts and click OK.

產生的專案會提供ASP.NET Core 身分識別做為Razor 類別庫The generated project provides ASP.NET Core Identity as a Razor Class Library. 身分識別 Razor 類別庫會公開具有 Identity 區域的端點。The Identity Razor Class Library exposes endpoints with the Identity area. 例如:For example:

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

套用移轉Apply migrations

套用遷移來初始化資料庫。Apply the migrations to initialize the database.

在 [套件管理員主控台] (PMC)中執行下列命令:Run the following command in the Package Manager Console (PMC):

PM> Update-Database

測試註冊和登入Test Register and Login

執行應用程式並註冊使用者。Run the app and register a user. 視您的螢幕大小而定,您可能需要選取 [流覽] 切換按鈕,才能看到 [註冊] 和 [登入] 連結。Depending on your screen size, you might need to select the navigation toggle button to see the Register and Login links.

檢視識別資料庫View the Identity database

  • 檢視功能表上,選取SQL Server 物件總管(SSOX)。From the View menu, select SQL Server Object Explorer (SSOX).
  • 瀏覽至 (localdb) (SQL Server 13) MSSQLLocalDBNavigate to (localdb)MSSQLLocalDB(SQL Server 13). 以滑鼠右鍵按一下dbo。AspNetUsers > 檢視資料:Right-click on dbo.AspNetUsers > View Data:

SQL Server 物件總管 中的 AspNetUsers 資料表上的操作功能表

設定身分識別服務Configure Identity services

服務會在 ConfigureServices 中新增。Services are added in ConfigureServices. 典型模式是呼叫所有 Add{Service} 方法,然後呼叫 services.Configure{Service} 方法。The typical pattern is to call all the Add{Service} methods, and then call all the services.Configure{Service} methods.

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            Configuration.GetConnectionString("DefaultConnection")));
    services.AddDefaultIdentity<IdentityUser>()
        .AddDefaultUI(UIFramework.Bootstrap4)
        .AddEntityFrameworkStores<ApplicationDbContext>();

    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;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

上述程式碼會使用預設選項值來設定身分識別。The preceding code configures Identity with default option values. 服務可透過相依性插入提供給應用程式。Services are made available to the app through dependency injection.

藉由呼叫UseAuthentication來啟用身分識別。Identity is enabled by calling UseAuthentication. UseAuthentication 會將驗證中介軟體新增至要求管線。UseAuthentication adds authentication middleware to the request pipeline.

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

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

    app.UseAuthentication();

    app.UseMvc();
}

如需詳細資訊,請參閱IdentityOptions 類別應用程式啟動For more information, see the IdentityOptions Class and Application Startup.

Scaffold 註冊、登入和登出Scaffold Register, Login, and LogOut

Scaffold 身分識別遵循具有授權指示的 Razor 專案,以產生本節所示的程式碼。Follow the Scaffold identity into a Razor project with authorization instructions to generate the code shown in this section.

新增註冊、登入和登出檔案。Add the Register, Login, and LogOut files.

檢查 RegisterExamine Register

當使用者按一下 [註冊] 連結時,就會叫用 RegisterModel.OnPostAsync 動作。When a user clicks the Register link, the RegisterModel.OnPostAsync action is invoked. 使用者是透過CreateAsync_userManager 物件上建立的。The user is created by CreateAsync on the _userManager object. _userManager 是由相依性插入所提供):_userManager is provided by dependency injection):

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl = returnUrl ?? Url.Content("~/");
    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);
            var callbackUrl = Url.Page(
                "/Account/ConfirmEmail",
                pageHandler: null,
                values: new { 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>.");

            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();
}

如果成功建立使用者,則會透過呼叫 _signInManager.SignInAsync 來登入使用者。If the user was created successfully, the user is logged in by the call to _signInManager.SignInAsync.

注意: 請參閱帳戶確認以取得在註冊時防止立即登入的步驟。Note: See account confirmation for steps to prevent immediate login at registration.

登錄Log in

登入表單的顯示時機如下:The Login form is displayed when:

  • 已選取 [登入] 連結。The Log in link is selected.
  • 使用者嘗試存取未獲授權存取的受限制頁面,其未經過系統驗證的情況。A user attempts to access a restricted page that they aren't authorized to access or when they haven't been authenticated by the system.

當登入頁面上的表單提交時,會呼叫 OnPostAsync 動作。When the form on the Login page is submitted, the OnPostAsync action is called. PasswordSignInAsync 是在 _signInManager 物件上呼叫(由相依性插入所提供)。PasswordSignInAsync is called on the _signInManager object (provided by dependency injection).

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();
}

基底 Controller 類別會公開您可以從控制器方法存取的 User 屬性。The base Controller class exposes a User property that you can access from controller methods. 例如,您可以列舉 User.Claims 並做出授權決策。For instance, you can enumerate User.Claims and make authorization decisions. 如需詳細資訊,請參閱介紹 ASP.NET Core 的授權For more information, see 介紹 ASP.NET Core 的授權.

登出Log out

[登出] 連結會叫用 LogoutModel.OnPost 動作。The Log out link invokes the LogoutModel.OnPost action.

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
            {
                // This needs to be a redirect so that the browser performs a new
                // request and the identity for the user gets updated.
                return RedirectToPage();
            }
        }
    }
}

SignOutAsync會清除儲存在 cookie 中的使用者宣告。SignOutAsync clears the user's claims stored in a cookie.

Post 是在Pages/Shared/_LoginPartial中指定的:Post is specified in the 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

預設的 Web 專案範本允許匿名存取首頁。The default web project templates allow anonymous access to the home pages. 若要測試身分識別,請將[Authorize]新增至 [隱私權] 頁面。To test Identity, add [Authorize] to the Privacy page.

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

namespace WebApp1.Pages
{
    [Authorize]
    public class PrivacyModel : PageModel
    {
        public void OnGet()
        {
        }
    }
}

如果您已登入,請登出。執行應用程式並選取 [隱私權] 連結。If you are signed in, sign out. Run the app and select the Privacy link. 系統會將您重新導向至登入頁面。You are redirected to the login page.

探索身分識別Explore Identity

若要更詳細地探索身分識別:To explore Identity in more detail:

身分識別元件Identity Components

所有身分識別相依的 NuGet 套件都包含在AspNetCore 應用程式中繼套件中。All the Identity dependent NuGet packages are included in the Microsoft.AspNetCore.App metapackage.

身分識別的主要套件是AspNetCore。The primary package for Identity is Microsoft.AspNetCore.Identity. 此套件包含 ASP.NET Core 身分識別的核心介面集,而且是由 Microsoft.AspNetCore.Identity.EntityFrameworkCore 所包含。This package contains the core set of interfaces for ASP.NET Core Identity, and is included by Microsoft.AspNetCore.Identity.EntityFrameworkCore.

遷移至 ASP.NET Core 身分識別Migrating to ASP.NET Core Identity

如需有關遷移現有身分識別存放區的詳細資訊和指引,請參閱遷移驗證和身分識別For more information and guidance on migrating your existing Identity store, see Migrate Authentication and Identity.

設定密碼強度Setting password strength

如需設定最小密碼需求的範例,請參閱設定。See Configuration for a sample that sets the minimum password requirements.

後續步驟Next Steps