在 ASP.NET Core Blazor Web Apps 中实现通行密钥

本指南介绍如何使用 ASP.NET Core 为新的或现有的Blazor Web AppIdentity。

有关通行密钥和常规配置指南的概述,请参阅 “启用 Web 身份验证 API”(WebAuthn)密钥

先决条件

.NET 10 SDK

创建 Blazor Web App

使用以下指南创建新的 Blazor Web App ASP.NET Core Identity,其中包括密钥支持。

注释

需要 Visual Studio 2022 或更高版本和 .NET 10 或更高版本的 SDK。

在 Visual Studio 中:

  • 从启动窗口选择“创建新项目”,或者从菜单栏选择“文件”“新建”“项目”。>>
  • 在“创建新项目”对话框中,从项目模板列表中选择“Blazor Web App”。 选择“下一步”按钮。
  • 在“配置新项目”对话框中,在“项目名称”字段中将项目命名为 (包括匹配大写)。BlazorWebAppPasskeys 使用此确切的项目名称非常重要,以确保命名空间与从项目复制到要生成的应用中的代码匹配。
  • 确认应用的位置是否合适。 将“将解决方案和项目放在同一目录中”复选框保持在选中状态。 选择“下一步”按钮。
  • 在“ 其他信息 ”对话框中,将 “身份验证类型 ”设置为 “个人帐户”。 对其他选项使用以下设置:
    • 框架:最新框架版本(.NET 10 或更高版本)
    • 配置 HTTPS:选中
    • 交互式呈现模式:服务器
    • 交互位置全局
    • 包括示例页面:选中
    • 不使用顶级语句:未选择
    • 在应用程序 URL 中使用 .dev.localhost TLD:未选中
    • 选择 创建

上述说明使用以下命令创建:Blazor Web App

  • ASP.NET 使用Identity为用户身份验证配置的 Core-au|--authentication
  • 用于数据存储的 SQLite 的 Entity Framework Core。
  • 密码注册和身份验证终结点。
  • 用于管理密钥的 UI 组件。

注释

目前,只有 Blazor Web App 项目模板包含内置密码支持。

运行应用程序

F5 通过调试运行应用,或 按 Ctrl+F5 运行应用,而无需调试。

以下指南依赖于使用 个人帐户 为应用 身份验证类型 创建的应用,或 将基架搭建 Identity 到现有应用中

先决条件

  • 具有 ASP.NET Core 的现有 Blazor Web App (.NET 10 或更高版本) Identity
  • .NET 10 SDK

有关迁移指南,请参阅 迁移 ASP.NET 核心应用

参考源指南

本文中指向 .NET 引用源的链接加载存储库的默认分支,该分支表示下一版本的 .NET 的当前开发。 若要为特定版本选择标记,请使用“切换分支或标记”下拉菜单。 有关详细信息,请参阅如何选择 ASP.NET Core 源代码的版本标记 (dotnet/AspNetCore.Docs #26205)

更新 Identity 架构版本

在中 Program.cs,更新 Identity 配置以使用架构版本 3,其中包括密钥支持:

builder.Services.AddIdentityCore<ApplicationUser>(options =>
{
    options.SignIn.RequireConfirmedAccount = true;
    options.Stores.SchemaVersion = IdentitySchemaVersions.Version3;
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddSignInManager()
.AddDefaultTokenProviders();

创建和运行数据库迁移

在 Visual Studio 解决方案资源管理器中,双击 “连接服务”。 在“服务依赖项”区域中,选择省略号(...),然后在 SQL Server Express LocalDB 区域中添加迁移

为迁移提供描述迁移的AddPasskeySupport。 等待数据库上下文在 DbContext 类名 字段中加载。 选择 “完成 ”以创建迁移。 作完成后,选择 “关闭 ”按钮。

再次选择省略号(...),后跟 “更新数据库 ”命令。

此时会打开 包含最新迁移对话框的“更新数据库 ”。 等待 DbContext 类名 字段更新,以及之前要加载的迁移。 选择“ 完成 ”按钮。 作完成后,选择 “关闭 ”按钮。

创建 passkey 模型类

将以下模型类添加到Components/Account文件夹中的项目,其中包含BlazorWebCSharp._1.Components.Account应用的命名空间更新(例如: Contoso.Components.Account

PasskeySubmit创建组件

添加以下 PasskeySubmit 组件来处理密钥作:

Components/Account/Shared/PasskeySubmit.razor

添加用于传递密钥作的 JavaScript

添加以下 JavaScript 文件以处理 WebAuthn API 交互:

Components/Account/Shared/PasskeySubmit.razor.js

添加通行密钥终结点

IdentityComponentsEndpointRouteBuilderExtensions.cs更新文件(如果文件不存在并调用MapAdditionalIdentityEndpointsProgram该文件),以包含特定于密钥的终结点:

/PasskeyCreationOptions/PasskeyRequestOptions 终结点

更新登录页

将现有Login组件替换为以下组件,并更新BlazorWebCSharp._1.Data命名空间以匹配应用(例如: Contoso.Components.Account.Data

Components/Account/Pages/Login.razor

将重定向方法添加到 IdentityRedirectManager

将以下方法添加到 IdentityRedirectManager 类中 Components/Account/IdentityRedirectManager.cs

public void RedirectToInvalidUser(
    UserManager<ApplicationUser> userManager, HttpContext context) =>
        RedirectToWithStatus("Account/InvalidUser",
            $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.",
            context);

创建用于添加和重命名通行密钥的通行密钥管理页

添加以下Passkeys组件以管理密钥并更新BlazorWebCSharp._1.Data命名空间以匹配应用(例如: Contoso.Components.Account.Data

Components/Account/Pages/Manage/Passkeys.razor

添加以下RenamePasskey组件以重命名密码并更新BlazorWebCSharp._1.Data命名空间以匹配应用(例如: Contoso.Components.Account.Data

Components/Account/Pages/Manage/RenamePasskey.razor

更新管理导航菜单

在应用的 ManageNavMenu 组件中添加指向密钥管理页的链接。

Components/Account/Shared/ManageNavMenu.razor中,为NavLink组件添加以下

<li class="nav-item">
    <NavLink class="nav-link" href="Account/Manage/Passkeys">Passkeys</NavLink>
</li>

包括 JavaScript 文件

App 组件(Components/App.razor)中找到 Blazor 脚本 标记:

<script src="_framework/blazor.web.js"></script>

在紧邻 Blazor 脚本标记之后,添加对 PasskeySubmit JavaScript 模块的引用:

<script src="Components/Account/Shared/PasskeySubmit.razor.js" type="module"></script>

注册密钥

测试 passkey 功能:

  1. 注册新帐户或使用现有帐户登录。
  2. 导航到 “管理帐户 ”(选择导航菜单中的用户名)。
  3. 从导航菜单中选择 Passkeys
  4. 选择 “添加新密钥”
  5. 按照浏览器的提示使用设备的验证器创建密码。

使用密钥登录

注册通行密钥后:

  1. 注销应用。
  2. 在登录页上,输入电子邮件地址。
  3. 选择 “使用密钥登录”。
  4. 按照浏览器的提示使用密码进行身份验证。
  5. 导航到 Account/Manage/Passkeys 添加、重命名或删除密钥。
  6. 如果 passkey 支持通过密钥自动填充(条件 UI)进行登录,则通过在保存通行密钥时选择电子邮件输入字段来测试通行密钥自动填充功能。

缓解 PublicKeyCredential.toJSON 错误 (TypeError: Illegal invocation

某些密码管理器无法正确实现 PublicKeyCredential.toJSON 方法,此方法对于在序列化密钥凭据时使 JSON.stringify 正常工作是必需的。 使用基于 Blazor Web App 项目模板的应用注册或验证用户时,尝试添加通行密钥时,将引发以下错误:

Error: Could not add a passkey: Illegal invocation

有关缓解此错误的指导,请参阅 “启用 Web 身份验证 API”(WebAuthn)密钥

其他资源