在 ASP.NET Core 專案中建構 Identity

作者:Rick Anderson

ASP.NET Core 會提供 ASP.NET Core Identity 作為 Razor 類別庫。 包含 Identity 的應用程式可以套用框架,以選擇性新增 IdentityRazor 類別庫 (RCL) 中包含的原始程式碼。 建議您產生原始程式碼,以便能夠修改程式碼並變更行為。 例如,您可以指示 Scaffolder 產生註冊使用的程式碼。 產生的程式碼優先於 Identity RCL 中的相同程式碼。 若要取得 UI 的完整控制權,而不使用預設 RCL,請參閱建立完整 Identity UI 來源一節。

包含驗證的應用程式可以套用框架來新增 RCL Identity 套件。 您可以選擇選取要產生的 Identity 程式碼。

雖然框架會產生大部分必要的程式碼,但您需要更新專案以完成程式。 本文件說明完成 Identity 建構更新所需的步驟。

建議您使用原始檔控制系統來顯示檔案差異,並可讓您退出變更。 在執行 Identity 框架之後檢查變更。

使用雙因素驗證帳戶確認和密碼復原,以及其他具有 Identity 的安全性功能時都需要服務。 在產生 Identity 時不會產生服務或服務存根。 啟用這些功能的服務必須手動新增。 例如,請參閱要求電子郵件確認

一般而言,使用個別帳戶建立的應用程式應該建立新的資料內容。

在沒有現有授權的情況下,將 Identity 建置至 Razor 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

移轉、UseAuthentication 和配置

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

版面配置變更

選擇性:將登入部分 (_LoginPartial) 新增至版面配置檔案:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</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">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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 justify-content-between">
                    <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>
                    <partial name="_LoginPartial" />
                </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; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

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

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

使用授權將 Identity 建置至 Razor 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

在沒有現有授權的情況下,將 Identity 建置至 MVC 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

選擇性:將登入部分 (_LoginPartial) 新增至 Views/Shared/_Layout.cshtml 檔案:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</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">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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 justify-content-between">
                    <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>
                    <partial name="_LoginPartial" />
                </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; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

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

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

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

MapRazorPages 新增至 Program.cs,如下列醒目提示的程式碼所示:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMVCauth.Data;

var builder = WebApplication.CreateBuilder(args);

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

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

var app = builder.Build();

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

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

app.UseRouting();

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

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

app.Run();

使用授權將 Identity 建置至 MVC 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

用戶端 Blazor 應用程式

用戶端 Blazor 應用程式會使用自己的 Identity UI 方法,而且無法使用 ASP.NET Core Identity 進行建構。

伺服器端 ASP.NET Core 應用程式可以遵循 Razor 本文中的 Pages/MVC 指引,並且設定的方式就像支援 的任何其他 ASP.NET Core 應用程式 Identity類型一樣。 架構Blazor會在將元件版本 (.razor) Identity UI 頁面 (.cshtml) 建Identity構成 Blazor Web 應用程式時使用Razor。

如需詳細資訊,請參閱 Blazor 安全性和 Identity 文章

建立完整的 Identity UI 來源

若要維護 UI 的完整控制權 Identity ,請執行 Identity 建構並選取 [ 覆寫所有檔案 ]。

密碼設定

如果在 Startup.ConfigureServices 中設定 PasswordOptions[StringLength] 屬性組態可能需要已建構 Identity 頁面中的 Password 屬性。 InputModelPassword 屬性可在下列檔案中找到:

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

停用頁面

本節說明如何停用註冊頁面,但該方法可用來停用任何頁面。

若要停用使用者註冊:

  • Scaffold Identity。 包含 Account.Register、Account.Login 和 Account.RegisterConfirmation。 例如:

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml.cs,讓使用者無法從此端點註冊:

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml 以與上述變更一致:

    @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>
    
  • 將註冊連結批註化或從 Areas/Identity/Pages/Account/Login.cshtml 中移除

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

    • 從 cshtml 檔案移除程式碼和連結。
    • PageModel 移除確認碼:
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

使用另一個應用程式來新增使用者

提供在 Web 應用程式外部新增使用者的機制。 新增使用者的選項包括:

  • 專用的管理員 Web 應用程式。
  • 主控台應用程式。

下列程式碼概述一種新增使用者的方法:

  • 使用者清單會讀取到記憶體中。
  • 系統會為每個使用者產生唯一強式密碼。
  • 使用者會新增至 Identity 資料庫。
  • 系統會通知使用者並被告知要變更密碼。
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>();
            });
}

下列程式碼概述新增使用者:


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

針對生產案例,可以遵循類似的方法。

防止靜態 Identity 資產發佈

若要防止將靜態 Identity 資產發佈至 Web 根目錄,請參閱 ASP.NET Core 上的 Identity 簡介

ASP.NET Core 會提供 ASP.NET Core Identity 作為 Razor 類別庫。 包含 Identity 的應用程式可以套用框架,以選擇性新增 IdentityRazor 類別庫 (RCL) 中包含的原始程式碼。 建議您產生原始程式碼,以便能夠修改程式碼並變更行為。 例如,您可以指示 Scaffolder 產生註冊使用的程式碼。 產生的程式碼優先於 Identity RCL 中的相同程式碼。 若要取得 UI 的完整控制權,而不使用預設 RCL,請參閱建立完整 Identity UI 來源一節。

包含驗證的應用程式可以套用框架來新增 RCL Identity 套件。 您可以選擇選取要產生的 Identity 程式碼。

雖然框架會產生大部分必要的程式碼,但您需要更新專案以完成程式。 本文件說明完成 Identity 建構更新所需的步驟。

建議您使用原始檔控制系統來顯示檔案差異,並可讓您退出變更。 在執行 Identity 框架之後檢查變更。

使用雙因素驗證帳戶確認和密碼復原,以及其他具有 Identity 的安全性功能時都需要服務。 在產生 Identity 時不會產生服務或服務存根。 啟用這些功能的服務必須手動新增。 例如,請參閱要求電子郵件確認

一般而言,使用個別帳戶建立的應用程式應該建立新的資料內容。

在沒有現有授權的情況下,將 Identity 建置至 Razor 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

移轉、UseAuthentication 和配置

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

版面配置變更

選擇性:將登入部分 (_LoginPartial) 新增至版面配置檔案:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</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">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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 justify-content-between">
                    <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>
                    <partial name="_LoginPartial" />
                </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; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

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

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

使用授權將 Identity 建置至 Razor 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

在沒有現有授權的情況下,將 Identity 建置至 MVC 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

選擇性:將登入部分 (_LoginPartial) 新增至 Views/Shared/_Layout.cshtml 檔案:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - WebRPnoAuth2Auth</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
    <link rel="stylesheet" href="~/WebRPnoAuth2Auth.styles.css" asp-append-version="true" />
</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">WebRPnoAuth2Auth</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-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 justify-content-between">
                    <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>
                    <partial name="_LoginPartial" />
                </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; 2021 - WebRPnoAuth2Auth - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

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

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

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

MapRazorPages 新增至 Program.cs,如下列醒目提示的程式碼所示:

using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebMVCauth.Data;

var builder = WebApplication.CreateBuilder(args);

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

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

var app = builder.Build();

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

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

app.UseRouting();

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

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

app.Run();

使用授權將 Identity 建置至 MVC 專案

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

使用授權將 Identity 建置至伺服器端 Blazor 應用程式

安裝 Microsoft.VisualStudio.Web.CodeGeneration.Design NuGet 套件。

注意

如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件)安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。


執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

移轉

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

樣式驗證端點

因為伺服器端 Blazor 應用程式使用 Razor Pages Identity 頁面,因此當訪客在頁面和元件之間 Identity 巡覽時,UI 的樣式會變更。 您有兩個選項可解決不一致樣式:

自訂 Identity 元件

ASP.NET Core Identity 的設計目的是在 HTTP 要求和回應通訊的內容中運作,這不是 Blazor 應用程式中的主要用戶端-伺服器通訊模型。 使用 ASP.NET Core Identity 來管理使用者的 ASP.NET Core 應用程式,應該使用 Razor Pages 而非 Razor 元件來取得 Identity 相關 UI,例如使用者註冊、登入、登出和其他使用者管理工作。

由於 Razor 元件不支援 SignInManager<TUser>UserManager<TUser>,因此我們建議使用 Web API 透過伺服器端支援 Identity 的 ASP.NET Core 應用程式來管理來自 Razor 元件的 Identity 動作。 如需為 Blazor 應用程式建立 Web API 的指引,請參閱從 ASP.NET Core Blazor 應用程式呼叫 Web API

使用 Razor 元件取代 Razor 頁面進行 Identity 的方法,是建立自己的自訂 IdentityRazor 元件,但 Microsoft 不建議或不支援這種方法。 如需其他內容,請探索下列討論。 在下列討論中,Microsoft 不支援在非 Microsoft GitHub 存放庫中交叉連結的問題批註和程式碼範例中的程式碼範例,但對某些開發人員可能很有説明:

如需尋求建置自訂 IdentityRazor 元件或搜尋協力廠商 Razor 元件時的其他協助,建議您使用下列資源:

搭配 Blazor 應用程式樣式使用自訂版面配置

您可以修改 Identity 版面配置和樣式,以產生使用類似預設 Blazor 主題樣式的頁面。 該文件並未涵蓋此方法。

用戶端 Blazor 應用程式

用戶端 Blazor 應用程式會使用自己的 Identity UI 方法,而且無法使用 ASP.NET Core Identity 進行建構。 裝載 Blazor 解決方案的伺服器端 ASP.NET Core 應用程式可以遵循本文中的 Razor Pages/MVC 指引,並且設定的方式就像支援 Identity 的任何其他 ASP.NET Core 應用程式類型一樣。

Blazor 架構不包含 Identity UI 頁面的 Razor 元件版本。 Identity UI Razor 元件可以自訂建置或從不支援的協力廠商來源取得。

如需詳細資訊,請參閱 Blazor 安全性和 Identity 文章

建立完整的 Identity UI 來源

若要維護 UI 的完整控制權 Identity ,請執行 Identity 建構並選取 [ 覆寫所有檔案 ]。

密碼設定

如果在 Startup.ConfigureServices 中設定 PasswordOptions[StringLength] 屬性組態可能需要已建構 Identity 頁面中的 Password 屬性。 InputModelPassword 屬性可在下列檔案中找到:

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

停用頁面

本節說明如何停用註冊頁面,但該方法可用來停用任何頁面。

若要停用使用者註冊:

  • Scaffold Identity。 包含 Account.Register、Account.Login 和 Account.RegisterConfirmation。 例如:

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml.cs,讓使用者無法從此端點註冊:

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml 以與上述變更一致:

    @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>
    
  • 將註冊連結批註化或從 Areas/Identity/Pages/Account/Login.cshtml 中移除

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

    • 從 cshtml 檔案移除程式碼和連結。
    • PageModel 移除確認碼:
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

使用另一個應用程式來新增使用者

提供在 Web 應用程式外部新增使用者的機制。 新增使用者的選項包括:

  • 專用的管理員 Web 應用程式。
  • 主控台應用程式。

下列程式碼概述一種新增使用者的方法:

  • 使用者清單會讀取到記憶體中。
  • 系統會為每個使用者產生唯一強式密碼。
  • 使用者會新增至 Identity 資料庫。
  • 系統會通知使用者並被告知要變更密碼。
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>();
            });
}

下列程式碼概述新增使用者:


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

針對生產案例,可以遵循類似的方法。

防止靜態 Identity 資產發佈

若要防止將靜態 Identity 資產發佈至 Web 根目錄,請參閱 ASP.NET Core 上的 Identity 簡介

ASP.NET Core 會提供 ASP.NET Core Identity 作為 Razor 類別庫。 包含 Identity 的應用程式可以套用框架,以選擇性新增 IdentityRazor 類別庫 (RCL) 中包含的原始程式碼。 建議您產生原始程式碼,以便能夠修改程式碼並變更行為。 例如,您可以指示 Scaffolder 產生註冊使用的程式碼。 產生的程式碼優先於 Identity RCL 中的相同程式碼。 若要取得 UI 的完整控制權,而不使用預設 RCL,請參閱建立完整 Identity UI 來源一節。

包含驗證的應用程式可以套用框架來新增 RCL Identity 套件。 您可以選擇選取要產生的 Identity 程式碼。

雖然框架會產生大部分必要的程式碼,但您需要更新專案以完成程式。 本文件說明完成 Identity 建構更新所需的步驟。

建議您使用原始檔控制系統來顯示檔案差異,並可讓您退出變更。 在執行 Identity 框架之後檢查變更。

使用雙因素驗證帳戶確認和密碼復原,以及其他具有 Identity 的安全性功能時都需要服務。 在產生 Identity 時不會產生服務或服務存根。 啟用這些功能的服務必須手動新增。 例如,請參閱要求電子郵件確認

使用新的資料內容將 Identity 建構到具有現有個別帳戶的專案時:

  • Startup.ConfigureServices 中,移除對下列的呼叫:
    • AddDbContext
    • AddDefaultIdentity

例如,AddDbContextAddDefaultIdentity 會在下列程式碼中加上批註:

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

上述程式碼會批註 Areas/Identity/IdentityHostingStartup.cs 中重複的程式碼

一般而言,使用個別帳戶建立的應用程式應該建立新的資料內容。

將 Identity 建置成空的專案

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

使用類似下列的程式碼更新 Startup 類別:

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,但並非必要。 如需詳細資訊,請參閱 HTTP 嚴格的傳輸安全性通訊協定

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

在沒有現有授權的情況下,將 Identity 建置至 Razor 專案

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

Identity 是在 Areas/Identity/IdentityHostingStartup.cs 中設定的: 如需詳細資訊,請參閱 IHostingStartup

移轉、UseAuthentication 和配置

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

啟用驗證

使用類似下列的程式碼更新 Startup 類別:

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,但並非必要。 如需詳細資訊,請參閱 HTTP 嚴格的傳輸安全性通訊協定

版面配置變更

選擇性:將登入部分 (_LoginPartial) 新增至版面配置檔案:

<!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.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.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>

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

使用授權將 Identity 建置至 Razor 專案

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

某些 Identity 選項是在 Areas/Identity/IdentityHostingStartup.cs 中設定的。 如需詳細資訊,請參閱 IHostingStartup

在沒有現有授權的情況下,將 Identity 建置至 MVC 專案

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

選擇性:將登入部分 (_LoginPartial) 新增至 Views/Shared/_Layout.cshtml 檔案:

<!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.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.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.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.cshtml

Identity 是在 Areas/Identity/IdentityHostingStartup.cs 中設定的: 如需詳細資訊,請參閱 IHostingStartup。

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

使用類似下列的程式碼更新 Startup 類別:

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,但並非必要。 如需詳細資訊,請參閱 HTTP 嚴格的傳輸安全性通訊協定

使用授權將 Identity 建置至 MVC 專案

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

在沒有現有授權的情況下,將 Identity 建構入伺服器端 Blazor 應用程式

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

Identity 是在 Areas/Identity/IdentityHostingStartup.cs 中設定的。 如需詳細資訊,請參閱IHostingStartup

移轉

產生的 Identity 資料庫程式碼需要 Entity Framework Core 移轉。 如果尚未建立和套用至資料庫的 Identity 架構移轉,請建立移轉並更新資料庫。 例如,執行下列命令:

在 Visual Studio 套件管理員主控台中:

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

Add-Migration 命令的「建立Identity架構」名稱參數是任意的。 "CreateIdentitySchema" 描述了移轉。

如果 Identity 架構已經建立,但未套用至資料庫,則必須執行更新資料庫的命令:

在 Visual Studio 套件管理員主控台中,執行 Update-Database

Update-Database

您可以使用下列命令來確認 Identity 架構的應用程式。 命令的輸出包含「applied」資料行,以顯示要套用至資料庫的移轉。

在 Visual Studio 套件管理員主控台中,執行 Get-Migration

Get-Migration

如果有多個資料庫內容存在,請使用 -Context 參數指定內容。

樣式驗證端點

因為伺服器端 Blazor 應用程式使用 Razor Pages Identity 頁面,因此當訪客在頁面和元件之間 Identity 巡覽時,UI 的樣式會變更。 您有兩個選項可解決不一致樣式:

自訂 Identity 元件

使用 Identity 元件 (而非頁面) 的一種方法是建置 Identity 元件。 因為 Razor 元件不支援 SignInManagerUserManager ,因此請使用 Blazor 應用程式中的 Web API 端點來處理使用者帳戶動作。

搭配 Blazor 應用程式樣式使用自訂版面配置

您可以修改 Identity 版面配置和樣式,以產生使用類似預設 Blazor 主題樣式的頁面。 該文件並未涵蓋此方法。

使用授權將 Identity 建置至伺服器端 Blazor 應用程式

執行 Identity 框架:

  • 從 [方案總管] 中,以滑鼠右鍵按一下專案 >[新增]>[新增 Scaffold 項目]
  • 從 [新增 Scaffold 項目] 對話方塊的左窗格中,選取 Identity。 在中央窗格中選取 Identity。 選取新增按鈕。
  • 在 [新增 Identity] 對話方塊中,選取您想要的選項。
    • 如果您有 Identity (_Layout.cshtml) 的現有自訂版面配置頁面,請選取現有的版面配置頁面,以避免覆寫框架不正確的標記覆寫您的版面配置。 例如,選取下列其中一項:
      • 具有現有 Razor Pages 基礎結構的 Razor Pages 或 Blazor Server 專案的 Pages/Shared/_Layout.cshtml
      • MVC 專案的 Views/Shared/_Layout.cshtml 或具有現有 MVC 基礎設施的 Blazor Server 專案。
    • 針對資料內容 (DbCoNtext 類別):
      • 選取您的資料內容類別。 您必須選取至少一個檔案來新增您的資料內容。
      • 若要建立資料內容,並可能為 Identity 建立新的使用者類別,請選取 + 按鈕。 接受預設值或指定類別 (例如,適用於名為「Contoso」公司的 Contoso.Data.ApplicationDbContext)。 若要建立新的使用者類別,請選取 User 類別+按鈕,然後指定類別 (例如,適用於名為「Contoso」公司的 ContosoUser)。
    • 選取 [新增] 按鈕以執行框架。

某些 Identity 選項是在 Areas/Identity/IdentityHostingStartup.cs 中設定的。 如需詳細資訊,請參閱 IHostingStartup

用戶端 Blazor 應用程式

用戶端 Blazor 應用程式會使用自己的 Identity UI 方法,而且無法使用 ASP.NET Core Identity 進行建構。 裝載 Blazor 解決方案的伺服器端 ASP.NET Core 應用程式可以遵循本文中的 Razor Pages/MVC 指引,並且設定的方式就像支援 Identity 的任何其他 ASP.NET Core 應用程式類型一樣。

Blazor 架構不包含 Identity UI 頁面的 Razor 元件版本。 Identity UI Razor 元件可以自訂建置或從不支援的協力廠商來源取得。

如需詳細資訊,請參閱 Blazor 安全性和 Identity 文章

建立完整的 Identity UI 來源

若要維護 UI 的完整控制權 Identity ,請執行 Identity 建構並選取 [ 覆寫所有檔案 ]。

以下醒目提示的程式碼顯示在 ASP.NET Core 2.1 Web 應用程式中以 Identity 取代預設 Identity UI 的變更。 您可能想要執行此動作,以完全控制 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()
        .AddRazorPagesOptions(options =>
        {
            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 會在下列程式碼中被取代:

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

下列程式碼會設定 LoginPathLogoutPathAccessDeniedPath):

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

註冊 IEmailSender 實作,例如:

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

密碼設定

如果在 Startup.ConfigureServices 中設定 PasswordOptions[StringLength] 屬性組態可能需要已建構 Identity 頁面中的 Password 屬性。 InputModelPassword 屬性可在下列檔案中找到:

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

停用頁面

本節說明如何停用註冊頁面,但該方法可用來停用任何頁面。

若要停用使用者註冊:

  • Scaffold Identity。 包含 Account.Register、Account.Login 和 Account.RegisterConfirmation。 例如:

    dotnet aspnet-codegenerator identity -dc RPauth.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.RegisterConfirmation"
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml.cs,讓使用者無法從此端點註冊:

    public class RegisterModel : PageModel
    {
        public IActionResult OnGet()
        {
            return RedirectToPage("Login");
        }
    
        public IActionResult OnPost()
        {
            return RedirectToPage("Login");
        }
    }
    
  • 更新 Areas/Identity/Pages/Account/Register.cshtml 以與上述變更一致:

    @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>
    
  • 將註冊連結批註化或從 Areas/Identity/Pages/Account/Login.cshtml 中移除

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

    • 從 cshtml 檔案移除程式碼和連結。
    • PageModel 移除確認碼:
    [AllowAnonymous]
      public class RegisterConfirmationModel : PageModel
      {
          public IActionResult OnGet()
          {  
              return Page();
          }
      }
    

使用另一個應用程式來新增使用者

提供在 Web 應用程式外部新增使用者的機制。 新增使用者的選項包括:

  • 專用的管理員 Web 應用程式。
  • 主控台應用程式。

下列程式碼概述一種新增使用者的方法:

  • 使用者清單會讀取到記憶體中。
  • 系統會為每個使用者產生唯一強式密碼。
  • 使用者會新增至 Identity 資料庫。
  • 系統會通知使用者並被告知要變更密碼。
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>();
            });
}

下列程式碼概述新增使用者:


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

針對生產案例,可以遵循類似的方法。

防止靜態 Identity 資產發佈

若要防止將靜態 Identity 資產發佈至 Web 根目錄,請參閱 ASP.NET Core 上的 Identity 簡介

其他資源