IdentityASP.NET Core 專案中的 ScaffoldScaffold Identity in ASP.NET Core projects

作者:Rick AndersonBy Rick Anderson

ASP.NET Core 提供ASP.NET Core Identity 做為 Razor 類別庫ASP.NET Core provides ASP.NET Core Identity as a Razor Class Library. 包含的應用程式 Identity 可以套用 scaffolder,以選擇性地新增包含在 Identity Razor 類別庫(RCL)中的原始程式碼。Applications that include Identity can apply the scaffolder to selectively add the source code contained in the Identity Razor Class Library (RCL). 建議您產生原始程式碼,以便能夠修改程式碼並變更行為。You might want to generate source code so you can modify the code and change the behavior. 例如,您可以指示 Scaffolder 產生註冊使用的程式碼。For example, you could instruct the scaffolder to generate the code used in registration. 產生的程式碼優先于 RCL 中的相同程式碼 Identity 。Generated code takes precedence over the same code in the Identity RCL. 若要取得 UI 的完全控制,而不使用預設 RCL,請參閱建立完整的 Identity UI 來源一節。To gain full control of the UI and not use the default RCL, see the section Create full Identity UI source.

包含驗證的應用程式可以套用 scaffolder 來新增 RCL Identity 套件。Applications that do not include authentication can apply the scaffolder to add the RCL Identity package. 您可以選擇 Identity 要產生的程式碼。You have the option of selecting Identity code to be generated.

雖然 scaffolder 會產生大部分必要的程式碼,但您必須更新您的專案,才能完成流程。Although the scaffolder generates most of the necessary code, you need to update your project to complete the process. 本檔說明完成「基架構更新」所需的步驟 Identity 。This document explains the steps needed to complete an Identity scaffolding update.

我們建議使用會顯示檔案差異的原始檔控制系統,並可讓您備份變更。We recommend using a source control system that shows file differences and allows you to back out of changes. 執行 scaffolder 後檢查變更 Identity 。Inspect the changes after running the Identity scaffolder.

使用雙因素驗證帳戶確認和密碼復原,以及其他安全性功能時,都需要服務 Identity 。Services are required when using Two Factor Authentication, Account confirmation and password recovery, and other security features with Identity. 當樣板時,不會產生服務或服務存根 Identity 。Services or service stubs aren't generated when scaffolding Identity. 啟用這些功能的服務必須手動新增。Services to enable these features must be added manually. 例如,請參閱需要電子郵件確認For example, see Require Email Confirmation.

當 Identity 具有新資料內容的樣板加入具有現有個別帳戶的專案時:When scaffolding Identity with a new data context into a project with existing individual accounts:

  • 在中 Startup.ConfigureServices ,移除對的呼叫:In Startup.ConfigureServices, remove the calls to:
    • AddDbContext
    • AddDefaultIdentity

例如, AddDbContextAddDefaultIdentity 會在下列程式碼中加上批註:For example, AddDbContext and AddDefaultIdentity are commented out in the following code:

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.AddControllersWithViews();
    services.AddRazorPages();
}

前面的程式碼會批註區域/ Identity / Identity HostingStartup.cs中重複的程式碼The preceeding code comments out the code that is duplicated in Areas/Identity/IdentityHostingStartup.cs

一般而言,使用個別帳戶建立的應用程式應該建立新的資料內容。Typically, apps that were created with individual accounts should not create a new data context.

Scaffold Identity 至空的專案Scaffold Identity into an empty project

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

使用與 Startup 下列類似的程式碼來更新類別:Update the Startup class with code similar to the following:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

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

        app.UseRouting();

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

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

Scaffold Identity 至 Razor 沒有現有授權的專案Scaffold Identity into a Razor project without existing authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

Identity會在區域/ Identity / Identity HostingStartup.cs中設定。 is configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

遷移、UseAuthentication 和版面配置Migrations, UseAuthentication, and layout

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

啟用驗證Enable authentication

使用與 Startup 下列類似的程式碼來更新類別:Update the Startup class with code similar to the following:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    }

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

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

版面配置變更Layout changes

選擇性:將登入部分( _LoginPartial )新增至配置檔案:Optional: Add the login partial (_LoginPartial) to the layout file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRP</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>

Scaffold Identity 至 Razor 具有授權的專案Scaffold Identity into a Razor project with authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取現有的版面配置頁,讓您的版面配置檔案不會以不正確的標記覆寫。Select your existing layout page so your layout file isn't overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor 伺服器專案~/Pages/Shared/_Layout.cshtml for Razor Pages or Blazor Server projects with existing Razor Pages infrastructure
      • ~/Views/Shared/_Layout.cshtml適用于具有現有 MVC 基礎結構的 MVC 專案或 Blazor 伺服器專案~/Views/Shared/_Layout.cshtml for MVC projects or Blazor Server projects with existing MVC infrastructure
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案。Select your existing layout page, or your layout file will be overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

有些 Identity 選項是在Areas/ Identity / Identity HostingStartup.cs中設定。Some Identity options are configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

Scaffold Identity 至沒有現有授權的 MVC 專案Scaffold Identity into an MVC project without existing authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

選擇性:將登入部分( _LoginPartial )新增至Views/Shared/_Layout. cshtml檔案:Optional: Add the login partial (_LoginPartial) to the Views/Shared/_Layout.cshtml file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRP</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">WebRP</a>
                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
                    <partial name="_LoginPartial" />
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - WebRP - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    <script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

    @RenderSection("Scripts", required: false)
</body>
</html>
  • Pages/shared/_LoginPartial. cshtml檔案移至Views/shared/_LoginPartial. cshtmlMove the Pages/Shared/_LoginPartial.cshtml file to Views/Shared/_LoginPartial.cshtml

Identity會在區域/ Identity / Identity HostingStartup.cs中設定。 is configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱 IHostingStartup。For more information, see IHostingStartup.

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

使用與 Startup 下列類似的程式碼來更新類別:Update the Startup class with code similar to the following:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddRazorPages();
    }

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

        app.UseRouting();

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

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
            endpoints.MapRazorPages();
        });
    }
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

Scaffold Identity 至具有授權的 MVC 專案Scaffold Identity into an MVC project with authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取現有的版面配置頁,讓您的版面配置檔案不會以不正確的標記覆寫。Select your existing layout page so your layout file isn't overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor 伺服器專案~/Pages/Shared/_Layout.cshtml for Razor Pages or Blazor Server projects with existing Razor Pages infrastructure
      • ~/Views/Shared/_Layout.cshtml適用于具有現有 MVC 基礎結構的 MVC 專案或 Blazor 伺服器專案~/Views/Shared/_Layout.cshtml for MVC projects or Blazor Server projects with existing MVC infrastructure
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案。Select your existing layout page, or your layout file will be overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

Scaffold Identity 至 Blazor Server 沒有現有授權的專案Scaffold Identity into a Blazor Server project without existing authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

Identity會在區域/ Identity / Identity HostingStartup.cs中設定。 is configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

移轉Migrations

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

將 XSRF token 傳遞至應用程式Pass an XSRF token to the app

權杖可以傳遞給元件:Tokens can be passed to components:

  • 當驗證權杖已布建並儲存至驗證 cookie 時,可以將它們傳遞給元件。When authentication tokens are provisioned and saved to the authentication cookie, they can be passed to components.
  • Razor元件無法 HttpContext 直接使用,因此無法取得反要求偽造(XSRF)權杖,以在張貼到 Identity 的登出端點 /Identity/Account/Logout components can't use HttpContext directly, so there's no way to obtain an anti-request forgery (XSRF) token to POST to Identity's logout endpoint at /Identity/Account/Logout. XSRF token 可以傳遞給元件。An XSRF token can be passed to components.

如需詳細資訊,請參閱 ASP.NET Core Blazor Server 其他安全性案例For more information, see ASP.NET Core Blazor Server 其他安全性案例.

Pages/_Host. cshtml檔案中,在將它加入和類別之後,建立權杖 InitialApplicationState TokenProviderIn the Pages/_Host.cshtml file, establish the token after adding it to the InitialApplicationState and TokenProvider classes:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf

...

var tokens = new InitialApplicationState
{
    ...

    XsrfToken = Xsrf.GetAndStoreTokens(HttpContext).RequestToken
};

更新 App 元件(razor)以指派 InitialState.XsrfTokenUpdate the App component (App.razor) to assign the InitialState.XsrfToken:

@inject TokenProvider TokenProvider

...

TokenProvider.XsrfToken = InitialState.XsrfToken;

TokenProvider 主題中所示範的服務用於 LoginDisplay 下列版面配置和驗證流程變更一節中的元件。The TokenProvider service demonstrated in the topic is used in the LoginDisplay component in the following Layout and authentication flow changes section.

啟用驗證Enable authentication

Startup 類別中:In the Startup class:

  • 確認 Razor 已在中新增頁面服務 Startup.ConfigureServicesConfirm that Razor Pages services are added in Startup.ConfigureServices.
  • 如果使用TokenProvider,請註冊服務。If using the TokenProvider, register the service.
  • UseDatabaseErrorPage針對開發環境,在的應用程式產生器上呼叫 Startup.ConfigureCall UseDatabaseErrorPage on the application builder in Startup.Configure for the Development environment.
  • UseAuthentication UseAuthorization 在之後呼叫和 UseRoutingCall UseAuthentication and UseAuthorization after UseRouting.
  • 新增頁面的端點 Razor 。Add an endpoint for Razor Pages.
public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
    services.AddScoped<TokenProvider>();
}

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();
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

版面配置和驗證流程變更Layout and authentication flow changes

RedirectToLogin在專案根目錄中,將元件(RedirectToLogin)新增至應用程式的共用資料夾:Add a RedirectToLogin component (RedirectToLogin.razor) to the app's Shared folder in the project root:

@inject NavigationManager Navigation
@code {
    protected override void OnInitialized()
    {
        Navigation.NavigateTo("Identity/Account/Login?returnUrl=" +
            Uri.EscapeDataString(Navigation.Uri), true);
    }
}

LoginDisplay 元件(LoginDisplay)新增至應用程式的共用資料夾。 TokenProvider 服務會針對張貼至的登出端點的 HTML 表單,提供 XSRF token Identity :The TokenProvider service provides the XSRF token for the HTML form that POSTs to Identity's logout endpoint:

@using Microsoft.AspNetCore.Components.Authorization
@inject NavigationManager Navigation
@inject TokenProvider TokenProvider

<AuthorizeView>
    <Authorized>
        <a href="Identity/Account/Manage/Index">
            Hello, @context.User.Identity.Name!
        </a>
        <form action="/Identity/Account/Logout?returnUrl=%2F" method="post">
            <button class="nav-link btn btn-link" type="submit">Logout</button>
            <input name="__RequestVerificationToken" type="hidden" 
                value="@TokenProvider.XsrfToken">
        </form>
    </Authorized>
    <NotAuthorized>
        <a href="Identity/Account/Register">Register</a>
        <a href="Identity/Account/Login">Login</a>
    </NotAuthorized>
</AuthorizeView>

MainLayout 元件(Shared/MainLayout)中,將 LoginDisplay 元件加入至頂端資料列 <div> 元素的內容:In the MainLayout component (Shared/MainLayout.razor), add the LoginDisplay component to the top-row <div> element's content:

<div class="top-row px-4 auth">
    <LoginDisplay />
    <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>

樣式驗證端點Style authentication endpoints

由於會 Blazor Server 使用 Razor 頁面 Identity 頁面,因此當訪客在 Identity 頁面和元件之間流覽時,UI 的樣式會變更。Because Blazor Server uses Razor Pages Identity pages, the styling of the UI changes when a visitor navigates between Identity pages and components. 您有兩個選項可解決 incongruous 樣式:You have two options to address the incongruous styles:

組建 Identity 元件Build Identity components

不使用頁面的元件是用來 Identity 建立元件的方法 Identity 。An approach to using components for Identity instead of pages is to build Identity components. 因為 SignInManager UserManager 元件中不支援和 Razor ,所以請使用應用程式中的 API 端點 Blazor Server 來處理使用者帳戶動作。Because SignInManager and UserManager aren't supported in Razor components, use API endpoints in the Blazor Server app to process user account actions.

使用具有 Blazor 應用程式樣式的自訂版面配置Use a custom layout with Blazor app styles

您 Identity 可以修改頁面版面配置和樣式,以產生使用預設主題的頁面 Blazor 。The Identity pages layout and styles can be modified to produce pages that use the default Blazor theme.

注意

本節中的範例只是自訂的起點。The example in this section is merely a starting point for customization. 可能需要額外的工作,才能獲得最佳的使用者體驗。Additional work is likely required for the best user experience.

建立新的 NavMenu_IdentityLayout 元件(Shared/NavMenu_ Identity Layout)。Create a new NavMenu_IdentityLayout component (Shared/NavMenu_IdentityLayout.razor). 如需元件的標記和程式碼,請使用應用程式元件的相同內容 NavMenuShared/navmenu.cshtml)。For the markup and code of the component, use the same content of the app's NavMenu component (Shared/NavMenu.razor). 去除 NavLink 無法匿名連線的任何元件,因為元件中的自動重新導向在 RedirectToLogin 需要驗證或授權的元件中失敗。Strip out any NavLinks to components that can't be reached anonymously because automatic redirects in the RedirectToLogin component fail for components requiring authentication or authorization.

Pages/Shared/Layout檔案中,進行下列變更:In the Pages/Shared/Layout.cshtml file, make the following changes:

  • 將指示詞新增至檔案 Razor 頂端,以在共用資料夾中使用標籤協助程式和應用程式的元件:Add Razor directives to the top of the file to use Tag Helpers and the app's components in the Shared folder:

    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
    @using {APPLICATION ASSEMBLY}.Shared
    

    取代 {APPLICATION ASSEMBLY} 為應用程式的元件名稱。Replace {APPLICATION ASSEMBLY} with the app's assembly name.

  • <base> 標記和樣式表單新增 Blazor <link><head> 內容:Add a <base> tag and Blazor stylesheet <link> to the <head> content:

    <base href="~/" />
    <link rel="stylesheet" href="~/css/site.css" />
    
  • 將標記的內容變更 <body> 如下:Change the content of the <body> tag to the following:

    <div class="sidebar" style="float:left">
        <component type="typeof(NavMenu_IdentityLayout)" 
            render-mode="ServerPrerendered" />
    </div>
    
    <div class="main" style="padding-left:250px">
        <div class="top-row px-4">
            @{
                var result = Engine.FindView(ViewContext, "_LoginPartial", 
                    isMainPage: false);
            }
            @if (result.Success)
            {
                await Html.RenderPartialAsync("_LoginPartial");
            }
            else
            {
                throw new InvalidOperationException("The default Identity UI " +
                    "layout requires a partial view '_LoginPartial'.");
            }
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>
    
        <div class="content px-4">
            @RenderBody()
        </div>
    </div>
    
    <script src="~/Identity/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/Identity/js/site.js" asp-append-version="true"></script>
    @RenderSection("Scripts", required: false)
    <script src="_framework/blazor.server.js"></script>
    

Scaffold Identity 至 Blazor Server 具有授權的專案Scaffold Identity into a Blazor Server project with authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取現有的版面配置頁,讓您的版面配置檔案不會以不正確的標記覆寫。Select your existing layout page so your layout file isn't overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor 伺服器專案~/Pages/Shared/_Layout.cshtml for Razor Pages or Blazor Server projects with existing Razor Pages infrastructure
      • ~/Views/Shared/_Layout.cshtml適用于具有現有 MVC 基礎結構的 MVC 專案或 Blazor 伺服器專案~/Views/Shared/_Layout.cshtml for MVC projects or Blazor Server projects with existing MVC infrastructure
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案。Select your existing layout page, or your layout file will be overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

有些 Identity 選項是在Areas/ Identity / Identity HostingStartup.cs中設定。Some Identity options are configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

建立完整的 Identity UI 來源Create full Identity UI source

若要維持 UI 的完全控制 Identity ,請執行 Identity scaffolder,然後選取 [覆寫所有檔案]。To maintain full control of the Identity UI, run the Identity scaffolder and select Override all files.

下列反白顯示的程式碼顯示在 Identity Identity ASP.NET Core 2.1 web 應用程式中,將預設 UI 取代為的變更。The following highlighted code shows the changes to replace the default Identity UI with Identity in an ASP.NET Core 2.1 web app. 您可能想要這麼做,以擁有 UI 的完全控制權 Identity 。You might want to do this to have full control of the Identity UI.

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.AddIdentity<IdentityUser, IdentityRole>()
        // services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddRazorPagesOptions(options =>
        {
            options.AllowAreas = true;
            options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
            options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
        });

    services.ConfigureApplicationCookie(options =>
    {
        options.LoginPath = $"/Identity/Account/Login";
        options.LogoutPath = $"/Identity/Account/Logout";
        options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
    });

    // using Microsoft.AspNetCore.Identity.UI.Services;
    services.AddSingleton<IEmailSender, EmailSender>();
}

Identity下列程式碼會取代預設值:The default Identity is replaced in the following code:

services.AddIdentity<IdentityUser, IdentityRole>()
    // services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

下列程式碼會設定LoginPathLogoutPathAccessDeniedPathThe following code sets the LoginPath, LogoutPath, and AccessDeniedPath:

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = $"/Identity/Account/Login";
    options.LogoutPath = $"/Identity/Account/Logout";
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

註冊執行 IEmailSender ,例如:Register an IEmailSender implementation, for example:

// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
public class EmailSender : IEmailSender
{
    public Task SendEmailAsync(string email, string subject, string message)
    {
        return Task.CompletedTask;
    }
}

密碼設定Password configuration

如果 PasswordOptions 在中設定 Startup.ConfigureServices ,則 scaffold 頁面中的屬性可能需要 [StringLength] 屬性設定 Password Identity 。If PasswordOptions are configured in Startup.ConfigureServices, [StringLength] attribute configuration might be required for the Password property in scaffolded Identity pages. InputModel``Password在下列檔案中可找到屬性:InputModel Password properties are found in the following files:

  • Areas/Identity/Pages/Account/Register.cshtml.cs
  • Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

停用頁面Disable a page

本章節說明如何停用 [註冊] 頁面,但此方法可用來停用任何頁面。This sections show how to disable the register page but the approach can be used to disable any page.

若要停用使用者註冊:To disable user registration:

  • Scaffold Identity 。Scaffold Identity. 包含帳戶。註冊、帳戶、登入和帳戶. RegisterConfirmation。Include Account.Register, Account.Login, and Account.RegisterConfirmation. 例如:For example:

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • 更新區域/ Identity /Pages/Account/Register.cshtml.cs ,讓使用者無法從這個端點註冊:Update Areas/Identity/Pages/Account/Register.cshtml.cs so users can't register from this endpoint:

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • Areas/ Identity /Pages/Account/Register.cshtml更新為與前述變更一致:Update Areas/Identity/Pages/Account/Register.cshtml to be consistent with the preceding changes:

    @page
    @model RegisterModel
    @{
        ViewData["Title"] = "Go to Login";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
    
  • 批註外或移除區域/ Identity /Pages/Account/Login.cshtml的註冊連結Comment out or remove the registration link from Areas/Identity/Pages/Account/Login.cshtml

    @*
    <p>
        <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
    </p>
    *@
    
  • 更新 [區域/ Identity /Pages/Account/RegisterConfirmation ] 頁面。Update the Areas/Identity/Pages/Account/RegisterConfirmation page.

    • 移除來自 cshtml 檔案的程式碼和連結。Remove the code and links from the cshtml file.
    • 從移除確認碼 PageModelRemove the confirmation code from the PageModel:
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

使用另一個應用程式來新增使用者Use another app to add users

提供在 web 應用程式外部新增使用者的機制。Provide a mechanism to add users outside the web app. 新增使用者的選項包括:Options to add users include:

  • 專用的管理 web 應用程式。A dedicated admin web app.
  • 主控台應用程式。A console app.

下列程式碼概述新增使用者的一種方法:The following code outlines one approach to adding users:

  • 使用者清單會讀入記憶體中。A list of users is read into memory.
  • 為每個使用者產生強式唯一密碼。A strong unique password is generated for each user.
  • 使用者會新增至 Identity 資料庫。The user is added to the Identity database.
  • 系統會通知使用者,並告知您變更密碼。The user is notified and told to change the password.
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<AppDbCntx>();
                context.Database.Migrate();

                var config = host.Services.GetRequiredService<IConfiguration>();
                var userList = config.GetSection("userList").Get<List<string>>();

                SeedData.Initialize(services, userList).Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred adding users.");
            }
        }

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

下列程式碼概述如何新增使用者:The following code outlines adding a user:


public static async Task Initialize(IServiceProvider serviceProvider,
                                    List<string> userList)
{
    var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();

    foreach (var userName in userList)
    {
        var userPassword = GenerateSecurePassword();
        var userId = await EnsureUser(userManager, userName, userPassword);

        NotifyUser(userName, userPassword);
    }
}

private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
                                             string userName, string userPassword)
{
    var user = await userManager.FindByNameAsync(userName);

    if (user == null)
    {
        user = new IdentityUser(userName)
        {
            EmailConfirmed = true
        };
        await userManager.CreateAsync(user, userPassword);
    }

    return user.Id;
}

針對生產案例,可以遵循類似的方法。A similar approach can be followed for production scenarios.

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

若要防止將靜態 Identity 資產發行至 web 根目錄,請參閱 簡介 Identity ASP.NET CoreTo prevent publishing static Identity assets to the web root, see 簡介 Identity ASP.NET Core.

其他資源Additional resources

ASP.NET Core 2.1 和更新版本提供 Identity ASP.NET Core做為 Razor 類別庫ASP.NET Core 2.1 and later provides ASP.NET Core Identity as a Razor Class Library. 包含的應用程式 Identity 可以套用 scaffolder,以選擇性地新增包含在 Identity Razor 類別庫(RCL)中的原始程式碼。Applications that include Identity can apply the scaffolder to selectively add the source code contained in the Identity Razor Class Library (RCL). 建議您產生原始程式碼,以便能夠修改程式碼並變更行為。You might want to generate source code so you can modify the code and change the behavior. 例如,您可以指示 Scaffolder 產生註冊使用的程式碼。For example, you could instruct the scaffolder to generate the code used in registration. 產生的程式碼優先于 RCL 中的相同程式碼 Identity 。Generated code takes precedence over the same code in the Identity RCL. 若要取得 UI 的完全控制,而不使用預設 RCL,請參閱建立完整身分識別 UI 來源一節。To gain full control of the UI and not use the default RCL, see the section Create full identity UI source.

包含驗證的應用程式可以套用 scaffolder 來新增 RCL Identity 套件。Applications that do not include authentication can apply the scaffolder to add the RCL Identity package. 您可以選擇 Identity 要產生的程式碼。You have the option of selecting Identity code to be generated.

雖然 scaffolder 會產生大部分必要的程式碼,但您必須更新您的專案,才能完成此流程。Although the scaffolder generates most of the necessary code, you'll have to update your project to complete the process. 本檔說明完成「基架構更新」所需的步驟 Identity 。This document explains the steps needed to complete an Identity scaffolding update.

Identity執行 scaffolder 時,會在專案目錄中建立ScaffoldingReadme.txt檔案。When the Identity scaffolder is run, a ScaffoldingReadme.txt file is created in the project directory. ScaffoldingReadme.txt檔案包含完成樣板更新所需需求的一般指示 Identity 。The ScaffoldingReadme.txt file contains general instructions on what's needed to complete the Identity scaffolding update. 本檔包含比ScaffoldingReadme.txt檔案更完整的指示。This document contains more complete instructions than the ScaffoldingReadme.txt file.

我們建議使用會顯示檔案差異的原始檔控制系統,並可讓您備份變更。We recommend using a source control system that shows file differences and allows you to back out of changes. 執行 scaffolder 後檢查變更 Identity 。Inspect the changes after running the Identity scaffolder.

注意

使用雙因素驗證帳戶確認和密碼復原,以及其他安全性功能時,都需要服務 Identity 。Services are required when using Two Factor Authentication, Account confirmation and password recovery, and other security features with Identity. 當樣板時,不會產生服務或服務存根 Identity 。Services or service stubs aren't generated when scaffolding Identity. 啟用這些功能的服務必須手動新增。Services to enable these features must be added manually. 例如,請參閱需要電子郵件確認For example, see Require Email Confirmation.

Scaffold Identity 至空的專案Scaffold Identity into an empty project

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

將下列反白顯示的呼叫新增至 Startup 類別:Add the following highlighted calls to the Startup class:

public class Startup
{        
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseMvc();
    }
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

Scaffold Identity 至 Razor 沒有現有授權的專案Scaffold Identity into a Razor project without existing authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

Identity會在區域/ Identity / Identity HostingStartup.cs中設定。 is configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

遷移、UseAuthentication 和版面配置Migrations, UseAuthentication, and layout

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

啟用驗證Enable authentication

Configure 類別的方法中 Startup ,于之後呼叫UseAuthentication UseStaticFilesIn the Configure method of the Startup class, call UseAuthentication after UseStaticFiles:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

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

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

        app.UseMvc();
    }
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

版面配置變更Layout changes

選擇性:將登入部分( _LoginPartial )新增至配置檔案:Optional: Add the login partial (_LoginPartial) to the layout file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - RazorNoAuth8</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-page="/Index" class="navbar-brand">RazorNoAuth8</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-page="/Index">Home</a></li>
                    <li><a asp-page="/About">About</a></li>
                    <li><a asp-page="/Contact">Contact</a></li>
                </ul>
                <partial name="_LoginPartial" />
            </div>
        </div>
    </nav>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2018 - RazorNoAuth8</p>
        </footer>
    </div>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

Scaffold Identity 至 Razor 具有授權的專案Scaffold Identity into a Razor project with authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取現有的版面配置頁,讓您的版面配置檔案不會以不正確的標記覆寫。Select your existing layout page so your layout file isn't overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor 伺服器專案~/Pages/Shared/_Layout.cshtml for Razor Pages or Blazor Server projects with existing Razor Pages infrastructure
      • ~/Views/Shared/_Layout.cshtml適用于具有現有 MVC 基礎結構的 MVC 專案或 Blazor 伺服器專案~/Views/Shared/_Layout.cshtml for MVC projects or Blazor Server projects with existing MVC infrastructure
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案。Select your existing layout page, or your layout file will be overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

有些 Identity 選項是在Areas/ Identity / Identity HostingStartup.cs中設定。Some Identity options are configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱IHostingStartupFor more information, see IHostingStartup.

Scaffold Identity 至沒有現有授權的 MVC 專案Scaffold Identity into an MVC project without existing authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [加入新的 scaffold 專案] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add New Scaffolded Item dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案:Select your existing layout page, or your layout file will be overwritten with incorrect markup:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
      • 根據 blazorserver 預設,不會為 Razor Pages 或 MVC 設定從 Blazor 伺服器範本()建立的 Blazor 伺服器應用程式。Blazor Server apps created from the Blazor Server template (blazorserver) aren't configured for Razor Pages or MVC by default. 將 [版面配置頁] 專案保留空白。Leave the layout page entry blank.
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
  • 選取 [新增]。Select Add.

選擇性:將登入部分( _LoginPartial )新增至Views/Shared/_Layout. cshtml檔案:Optional: Add the login partial (_LoginPartial) to the Views/Shared/_Layout.cshtml file:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - MvcNoAuth3</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">MvcNoAuth3</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
                    <li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
                </ul>
                <partial name="_LoginPartial" />
            </div>
        </div>
    </nav>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2018 - MvcNoAuth3</p>
        </footer>
    </div>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
        </script>
        <script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>
  • Pages/shared/_LoginPartial. cshtml檔案移至Views/shared/_LoginPartial. cshtmlMove the Pages/Shared/_LoginPartial.cshtml file to Views/Shared/_LoginPartial.cshtml

Identity會在區域/ Identity / Identity HostingStartup.cs中設定。 is configured in Areas/Identity/IdentityHostingStartup.cs. 如需詳細資訊,請參閱 IHostingStartup。For more information, see IHostingStartup.

產生的身分識別資料庫程式碼需要Entity Framework Core 遷移The generated Identity database code requires Entity Framework Core Migrations. 建立遷移並更新資料庫。Create a migration and update the database. 例如,執行下列命令:For example, run the following commands:

在 [Visual Studio套件管理員主控台] 中:In the Visual Studio Package Manager Console:

Install-Package Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
Add-Migration CreateIdentitySchema
Update-Database

Add-Migration 命令的 "CreateIdentitySchema" 名稱參數是任意的。The "CreateIdentitySchema" name parameter for the Add-Migration command is arbitrary. "CreateIdentitySchema" 說明遷移。"CreateIdentitySchema" describes the migration.

在之後呼叫UseAuthentication UseStaticFilesCall UseAuthentication after UseStaticFiles:

public class Startup
{

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }

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

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseAuthentication();
        app.UseMvcWithDefaultRoute();
    }
}

UseHsts建議使用,但非必要。UseHsts is recommended but not required. 如需詳細資訊,請參閱HTTP Strict 傳輸安全性通訊協定For more information, see HTTP Strict Transport Security Protocol.

Scaffold Identity 至具有授權的 MVC 專案Scaffold Identity into an MVC project with authorization

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取現有的版面配置頁,讓您的版面配置檔案不會以不正確的標記覆寫。Select your existing layout page so your layout file isn't overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor 伺服器專案~/Pages/Shared/_Layout.cshtml for Razor Pages or Blazor Server projects with existing Razor Pages infrastructure
      • ~/Views/Shared/_Layout.cshtml適用于具有現有 MVC 基礎結構的 MVC 專案或 Blazor 伺服器專案~/Views/Shared/_Layout.cshtml for MVC projects or Blazor Server projects with existing MVC infrastructure
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

執行身分識別 scaffolder:Run the Identity scaffolder:

  • 方案總管中,以滑鼠右鍵按一下專案 > [加入 > 新的 scaffold 專案]。From Solution Explorer, right-click on the project > Add > New Scaffolded Item.
  • 從 [新增 Scaffold ] 對話方塊的左窗格中,選取 [身分識別] [ > 新增]。From the left pane of the Add Scaffold dialog, select Identity > Add.
  • 在 [新增識別] 對話方塊中,選取您想要的選項。In the Add Identity dialog, select the options you want.
    • 選取您現有的版面配置頁,否則會以不正確的標記覆寫您的配置檔案。Select your existing layout page, or your layout file will be overwritten with incorrect markup. 選取現有的* _ 版面配置. cshtml*檔案時,會覆寫該檔案。When an existing _Layout.cshtml file is selected, it is not overwritten. 例如:For example:
      • ~/Pages/Shared/_Layout.cshtml針對 Razor Pages~/Pages/Shared/_Layout.cshtml for Razor Pages
      • ~/Views/Shared/_Layout.cshtml針對 MVC 專案~/Views/Shared/_Layout.cshtml for MVC projects
  • 若要使用現有的資料內容,請至少選取一個要覆寫的檔案。To use your existing data context, select at least one file to override. 您必須至少選取一個檔案來新增資料內容。You must select at least one file to add your data context.
    • 選取您的資料內容類別。Select your data context class.
    • 選取 [新增]。Select Add.
  • 若要建立新的使用者內容,並可能建立身分識別的自訂使用者類別:To create a new user context and possibly create a custom user class for Identity:
    • 選取 [] + 按鈕以建立新的資料內容類別Select the + button to create a new Data context class. 接受預設值或指定類別(例如, MyApplication.Data.ApplicationDbContext )。Accept the default value or specify a class (for example, MyApplication.Data.ApplicationDbContext).
    • 選取 [新增]。Select Add.

注意:如果您要建立新的使用者內容,就不需要選取要覆寫的檔案。Note: If you're creating a new user context, you don't have to select a file to override.

刪除頁面/共用資料夾,以及該資料夾中的檔案。Delete the Pages/Shared folder and the files in that folder.

建立完整的 Identity UI 來源Create full Identity UI source

若要維持 UI 的完全控制 Identity ,請執行 Identity scaffolder,然後選取 [覆寫所有檔案]。To maintain full control of the Identity UI, run the Identity scaffolder and select Override all files.

下列反白顯示的程式碼顯示在 Identity Identity ASP.NET Core 2.1 web 應用程式中,將預設 UI 取代為的變更。The following highlighted code shows the changes to replace the default Identity UI with Identity in an ASP.NET Core 2.1 web app. 您可能想要這麼做,以擁有 UI 的完全控制權 Identity 。You might want to do this to have full control of the Identity UI.

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.AddIdentity<IdentityUser, IdentityRole>()
        // services.AddDefaultIdentity<IdentityUser>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
        .AddRazorPagesOptions(options =>
        {
            options.AllowAreas = true;
            options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
            options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");
        });

    services.ConfigureApplicationCookie(options =>
    {
        options.LoginPath = $"/Identity/Account/Login";
        options.LogoutPath = $"/Identity/Account/Logout";
        options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
    });

    // using Microsoft.AspNetCore.Identity.UI.Services;
    services.AddSingleton<IEmailSender, EmailSender>();
}

Identity下列程式碼會取代預設值:The default Identity is replaced in the following code:

services.AddIdentity<IdentityUser, IdentityRole>()
    // services.AddDefaultIdentity<IdentityUser>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultTokenProviders();

下列程式碼會設定LoginPathLogoutPathAccessDeniedPathThe following code sets the LoginPath, LogoutPath, and AccessDeniedPath:

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = $"/Identity/Account/Login";
    options.LogoutPath = $"/Identity/Account/Logout";
    options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
});

註冊執行 IEmailSender ,例如:Register an IEmailSender implementation, for example:

// using Microsoft.AspNetCore.Identity.UI.Services;
services.AddSingleton<IEmailSender, EmailSender>();
public class EmailSender : IEmailSender
{
    public Task SendEmailAsync(string email, string subject, string message)
    {
        return Task.CompletedTask;
    }
}

密碼設定Password configuration

如果 PasswordOptions 在中設定 Startup.ConfigureServices ,則 scaffold 頁面中的屬性可能需要 [StringLength] 屬性設定 Password Identity 。If PasswordOptions are configured in Startup.ConfigureServices, [StringLength] attribute configuration might be required for the Password property in scaffolded Identity pages. InputModel``Password在下列檔案中可找到屬性:InputModel Password properties are found in the following files:

  • Areas/Identity/Pages/Account/Register.cshtml.cs
  • Areas/Identity/Pages/Account/ResetPassword.cshtml.cs

停用註冊頁面Disable register page

若要停用使用者註冊:To disable user registration:

  • Scaffold Identity 。Scaffold Identity. 包含帳戶。註冊、帳戶、登入和帳戶. RegisterConfirmation。Include Account.Register, Account.Login, and Account.RegisterConfirmation. 例如:For example:

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • 更新區域/ Identity /Pages/Account/Register.cshtml.cs ,讓使用者無法從這個端點註冊:Update Areas/Identity/Pages/Account/Register.cshtml.cs so users can't register from this endpoint:

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • Areas/ Identity /Pages/Account/Register.cshtml更新為與前述變更一致:Update Areas/Identity/Pages/Account/Register.cshtml to be consistent with the preceding changes:

    @page
    @model RegisterModel
    @{
        ViewData["Title"] = "Go to Login";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <li class="nav-item">
        <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </li>
    
  • 批註外或移除區域/ Identity /Pages/Account/Login.cshtml的註冊連結Comment out or remove the registration link from Areas/Identity/Pages/Account/Login.cshtml

@*
<p>
    <a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
</p>
*@
  • 更新 [區域/ Identity /Pages/Account/RegisterConfirmation ] 頁面。Update the Areas/Identity/Pages/Account/RegisterConfirmation page.

    • 移除來自 cshtml 檔案的程式碼和連結。Remove the code and links from the cshtml file.
    • 從移除確認碼 PageModelRemove the confirmation code from the PageModel:
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

使用另一個應用程式來新增使用者Use another app to add users

提供在 web 應用程式外部新增使用者的機制。Provide a mechanism to add users outside the web app. 新增使用者的選項包括:Options to add users include:

  • 專用的管理 web 應用程式。A dedicated admin web app.
  • 主控台應用程式。A console app.

下列程式碼概述新增使用者的一種方法:The following code outlines one approach to adding users:

  • 使用者清單會讀入記憶體中。A list of users is read into memory.
  • 為每個使用者產生強式唯一密碼。A strong unique password is generated for each user.
  • 使用者會新增至 Identity 資料庫。The user is added to the Identity database.
  • 系統會通知使用者,並告知您變更密碼。The user is notified and told to change the password.
public class Program
{
    public static void Main(string[] args)
    {
        var host = CreateHostBuilder(args).Build();

        using (var scope = host.Services.CreateScope())
        {
            var services = scope.ServiceProvider;

            try
            {
                var context = services.GetRequiredService<AppDbCntx>();
                context.Database.Migrate();

                var config = host.Services.GetRequiredService<IConfiguration>();
                var userList = config.GetSection("userList").Get<List<string>>();

                SeedData.Initialize(services, userList).Wait();
            }
            catch (Exception ex)
            {
                var logger = services.GetRequiredService<ILogger<Program>>();
                logger.LogError(ex, "An error occurred adding users.");
            }
        }

        host.Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

下列程式碼概述如何新增使用者:The following code outlines adding a user:


public static async Task Initialize(IServiceProvider serviceProvider,
                                    List<string> userList)
{
    var userManager = serviceProvider.GetService<UserManager<IdentityUser>>();

    foreach (var userName in userList)
    {
        var userPassword = GenerateSecurePassword();
        var userId = await EnsureUser(userManager, userName, userPassword);

        NotifyUser(userName, userPassword);
    }
}

private static async Task<string> EnsureUser(UserManager<IdentityUser> userManager,
                                             string userName, string userPassword)
{
    var user = await userManager.FindByNameAsync(userName);

    if (user == null)
    {
        user = new IdentityUser(userName)
        {
            EmailConfirmed = true
        };
        await userManager.CreateAsync(user, userPassword);
    }

    return user.Id;
}

針對生產案例,可以遵循類似的方法。A similar approach can be followed for production scenarios.

其他資源Additional resources