簡介 Identity ASP.NET CoreIntroduction to Identity on ASP.NET Core

作者:Rick AndersonBy Rick Anderson

ASP.NET Core Identity :ASP.NET Core Identity:

  • 是支援使用者介面 (UI) 登入功能的 API。Is an API that supports user interface (UI) login functionality.
  • 管理使用者、密碼、設定檔資料、角色、宣告、權杖、電子郵件確認等等。Manages users, passwords, profile data, roles, claims, tokens, email confirmation, and more.

使用者可以建立具有儲存在中之登入資訊的帳戶, Identity 或可以使用外部登入提供者。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.

如需如何全域要求所有使用者進行驗證的相關資訊,請參閱要求已驗證的使用者For information on how to globally require all users to be authenticated, see Require authenticated users.

Identity 原始程式碼可在 GitHub 上取得。The Identity source code is available on GitHub. Scaffold Identity 和會查看產生的檔案,以檢查與的範本互動 Identity 。Scaffold Identity and view the generated files to review the template interaction with Identity.

Identity通常會使用 SQL Server 資料庫來設定,以儲存使用者名稱、密碼和設定檔資料。Identity is typically 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.

在本主題中,您將瞭解如何使用 Identity 來註冊、登入和登出使用者。In this topic, you learn how to use Identity to register, log in, and log out a user. 注意:範本會將使用者名稱和電子郵件視為相同。Note: the templates treat username and email as the same for users. 如需建立使用之應用程式的詳細指示 Identity ,請參閱後續步驟For more detailed instructions about creating apps that use Identity, see Next Steps.

Microsoft 身分識別平臺是:Microsoft identity platform is:

  • Azure Active Directory (Azure AD) 開發人員平臺的演進。An evolution of the Azure Active Directory (Azure AD) developer platform.
  • 與 ASP.NET Core 無關 Identity 。Unrelated to ASP.NET Core Identity.

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 的 OpenID Connect 和 OAuth 2.0 架構。IdentityServer4 is an OpenID Connect and OAuth 2.0 framework for ASP.NET Core. 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.

產生的專案會提供 Identity ASP.NET Core做為 Razor 類別庫The generated project provides ASP.NET Core Identity as a Razor Class Library. Identity Razor 類別庫會以區域公開端點 IdentityThe 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

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

SQL Server 物件總管中 AspNetUsers 資料表的相關功能表

設定 Identity 服務Configure Identity services

服務會在中加入 ConfigureServicesServices 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.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;
    });
}

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

Identity藉由呼叫來啟用 UseAuthenticationIdentity 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. UseRouting``UseAuthentication UseAuthorization UseEndpoints 必須以上述程式碼中所示的順序來呼叫、、和。UseRouting, UseAuthentication, UseAuthorization, and UseEndpoints must be called in the order shown in the preceding code.

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

Scaffold Register、Login、登出和 RegisterConfirmationScaffold Register, Login, LogOut, and RegisterConfirmation

新增 Register 、、 Login 和檔案 LogOut RegisterConfirmationAdd the Register, Login, LogOut, and RegisterConfirmation files. 遵循Scaffold 身分識別, Razor 並提供授權指示來產生本節所示的程式碼。Follow the Scaffold identity into a Razor project with authorization instructions to generate the code shown in this section.

檢查 RegisterExamine Register

當使用者按一下頁面上的 [註冊] 按鈕時 RegisterRegisterModel.OnPostAsync 就會叫用動作。When a user clicks the Register button on the Register page, the RegisterModel.OnPostAsync action is invoked. CreateAsync會在物件上建立使用者 _userManagerThe user is created by CreateAsync on the _userManager object:

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

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

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

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

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

停用預設帳戶驗證Disable default account verification

使用預設範本時,系統會將使用者重新導向至, Account.RegisterConfirmation 他們可以在其中選取連結以確認帳戶。With the default templates, the user is redirected to the Account.RegisterConfirmation where they can select a link to have the account confirmed. 預設 Account.RegisterConfirmation 用於測試,應在生產應用程式中停用自動帳戶驗證。The default Account.RegisterConfirmation is used only for testing, automatic account verification should be disabled in a production app.

若要在註冊時要求已確認的帳戶並防止立即登入,請 DisplayConfirmAccountLink = false/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs中設定:To require a confirmed account and prevent immediate login at registration, set DisplayConfirmAccountLink = false in /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();
    }
}

登入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會在物件上呼叫 _signInManagerPasswordSignInAsync is called on the _signInManager object.

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

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

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

如需有關如何進行授權決策的詳細資訊,請參閱 ASP.NET Core 的授權簡介For information on how to make authorization decisions, 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中指定的。 cshtml: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>

測驗IdentityTest Identity

預設的 Web 專案範本允許匿名存取首頁。The default web project templates allow anonymous access to the home pages. 若要測試 Identity ,請新增 [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.

看IdentityExplore Identity

若要 Identity 更詳細地探索:To explore Identity in more detail:

Identity要素Identity Components

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

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

遷移至 ASP.NET CoreIdentityMigrating to ASP.NET Core Identity

如需有關遷移現有存放區的詳細資訊和指引 Identity ,請參閱遷移驗證和 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.

AddDefault Identity 並新增IdentityAddDefaultIdentity 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:

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

防止發行靜態 Identity 資產Prevent publish of static Identity assets

若要防止將靜態 Identity 資產發行 (的樣式表單和 JavaScript 檔案,以供 Identity UI) 至 web 根目錄,請將下列 ResolveStaticWebAssetsInputsDependsOn 屬性和 RemoveIdentityAssets 目標新增至應用程式的專案檔:To prevent publishing static Identity assets (stylesheets and JavaScript files for Identity UI) to the web root, add the following ResolveStaticWebAssetsInputsDependsOn property and RemoveIdentityAssets target to the app's project file:

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

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

後續步驟Next Steps

作者:Rick AndersonBy Rick Anderson

ASP.NET Core Identity 是將登入功能新增至 ASP.NET Core 應用程式的成員資格系統。ASP.NET Core Identity is a membership system that adds login functionality to ASP.NET Core apps. 使用者可以建立具有儲存在中之登入資訊的帳戶, Identity 或可以使用外部登入提供者。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.

Identity可以使用 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).

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

AddDefault Identity 並新增IdentityAddDefaultIdentity 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:

如需詳細資訊,請參閱AddDefault Identity 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.

產生的專案會提供 Identity ASP.NET Core做為 Razor 類別庫The generated project provides ASP.NET Core Identity as a Razor Class Library. Identity Razor 類別庫會以區域公開端點 IdentityThe 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):

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

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

SQL Server 物件總管中 AspNetUsers 資料表的相關功能表

設定 Identity 服務Configure Identity services

服務會在中加入 ConfigureServicesServices 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);
}

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

Identity會藉由呼叫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();
}

如需詳細資訊,請參閱 Identity Options 類別應用程式啟動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會在物件上建立使用者 _userManagerThe user is created by CreateAsync on the _userManager object:

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.SignInAsyncIf 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會在物件上呼叫 _signInManagerPasswordSignInAsync is called on the _signInManager object.

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

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

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

如需有關如何進行授權決策的詳細資訊,請參閱 ASP.NET Core 的授權簡介For information on how to make authorization decisions, 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中指定的。 cshtml: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>


測驗IdentityTest Identity

預設的 Web 專案範本允許匿名存取首頁。The default web project templates allow anonymous access to the home pages. 若要進行測試 Identity ,請將新增 [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.

看IdentityExplore Identity

若要 Identity 更詳細地探索:To explore Identity in more detail:

Identity要素Identity Components

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

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

遷移至 ASP.NET CoreIdentityMigrating to ASP.NET Core Identity

如需有關遷移現有存放區的詳細資訊和指引 Identity ,請參閱遷移驗證和 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