练习 - 配置多重身份验证
在上一单元中,你了解了 ASP.NET Core Identity 如何实现基于时间的一次性密码(TOTP)进行多重身份验证(MFA)。 在本单元中,自定义现有的 “配置验证器”应用 表单,以提供包含注册密钥的 QR 码。
生成 QR 码
存在多个生成 QR 码的策略。 文档中的一个示例使用 客户端 JavaScript 库。 但是,在本单元中,第三方 NuGet 包用于在服务器上使用 C# 生成 QR 码。 生成的 QR 代码图像作为 base-64 编码字符串注入到 HTML 占位符元素中。
添加 QR 码服务
让我们在配置验证器应用窗体上构建生成QR码所需的一切。
在终端窗格中,安装
QRCoder
NuGet 包:dotnet add package QRCoder --version 1.6.0
在 “资源管理器” 窗格中,右键单击 “服务 ”文件夹,并添加名为 “QRCodeService.cs”的新文件。 添加以下代码:
using QRCoder; namespace RazorPagesPizza.Services; public class QRCodeService { private readonly QRCodeGenerator _generator; public QRCodeService(QRCodeGenerator generator) { _generator = generator; } public string GetQRCodeAsBase64(string textToEncode) { QRCodeData qrCodeData = _generator.CreateQrCode(textToEncode, QRCodeGenerator.ECCLevel.Q); var qrCode = new PngByteQRCode(qrCodeData); return Convert.ToBase64String(qrCode.GetGraphic(4)); } }
前面的代码:
- 使用构造函数注入来访问库类的
QRCodeGenerator
实例。 - 公开
GetQRCodeAsBase64
方法以返回 base-64 编码字符串。 传递给GetGraphic
的整数值决定了 QR 码的尺寸。 在这种情况下,生成的 QR 码由四个像素平方大小的块组成。
- 使用构造函数注入来访问库类的
在 Program.cs 中,添加突出显示的行:
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using RazorPagesPizza.Areas.Identity.Data; using Microsoft.AspNetCore.Identity.UI.Services; using RazorPagesPizza.Services; using QRCoder; var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("RazorPagesPizzaAuthConnection"); builder.Services.AddDbContext<RazorPagesPizzaAuth>(options => options.UseSqlServer(connectionString)); builder.Services.AddDefaultIdentity<RazorPagesPizzaUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<RazorPagesPizzaAuth>(); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddTransient<IEmailSender, EmailSender>(); builder.Services.AddSingleton(new QRCodeService(new QRCodeGenerator())); var app = builder.Build();
QRCodeService
在 Program.cs 的 IoC 容器中注册为单例服务。
自定义多重身份验证
生成 QR 码后,可以将 QR 码嵌入 到“配置验证器”应用 表单中。
打开 Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs 并进行以下更改:
若要存储 QR 码的 base-64 字符串表示形式,请将以下属性添加到
EnableAuthenticatorModel
类:public class EnableAuthenticatorModel : PageModel { private readonly UserManager<RazorPagesPizzaUser> _userManager; private readonly ILogger<EnableAuthenticatorModel> _logger; private readonly UrlEncoder _urlEncoder; public string QrCodeAsBase64 { get; set; }
纳入
OnGetAsync
页处理程序中突出显示的更改:public async Task<IActionResult> OnGetAsync([FromServices] QRCodeService qrCodeService) { var user = await _userManager.GetUserAsync(User); if (user == null) { return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."); } await LoadSharedKeyAndQrCodeUriAsync(user); QrCodeAsBase64 = qrCodeService.GetQRCodeAsBase64(AuthenticatorUri); return Page(); }
在前面的页处理程序中,参数注入提供对
QRCodeService
单一服务的引用。若要解析对
QRCodeService
的引用,请将以下using
语句添加到文件顶部。 保存更改。using RazorPagesPizza.Services;
将突出显示的更改纳入到
GenerateQrCodeUri
方法。private string GenerateQrCodeUri(string email, string unformattedKey) { return string.Format( CultureInfo.InvariantCulture, AuthenticatorUriFormat, _urlEncoder.Encode("RazorPagesPizza"), _urlEncoder.Encode(email), unformattedKey); }
这会设置 TOTP 应用中密钥的显示名称。
在 Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml中,进行以下突出显示的更改并保存:
<li> <p>Scan the QR Code or enter this key <kbd>@Model.SharedKey</kbd> into your two factor authenticator app. Spaces and casing do not matter.</p> <div class="alert alert-info">Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable QR code generation</a>.</div> <div id="qrCode"> <img alt="embedded QR code" src="data:image/png;base64,@Model.QrCodeAsBase64" /> </div> <div id="qrCodeData" data-url="@Model.AuthenticatorUri"></div> </li>
前面的标记在页面中嵌入 base-64 编码的图像。
测试多重身份验证
在“配置验证器应用”窗体上,你已对 QR 码做了所有需要的更改。 现在,可以轻松测试 MFA 功能。
确保保存了所有更改。
使用
dotnet run
.. 生成并运行应用。导航到站点,并使用任一已注册用户登录(如果尚未登录)。 选择 Hello,[名字] [姓氏]! 链接导航到配置文件管理页,然后选择 双重身份验证。
选择 “添加验证器应用 ”按钮。
按照屏幕上的说明注册并验证此用户的验证器应用。
例如,在 Android 上使用 Microsoft Authenticator,按照以下步骤将帐户添加到应用:
- 打开 Microsoft Authenticator 应用。
- 选择右上角的烤肉串菜单(垂直省略号)。
- 选择 “添加帐户”。
- 选择其他帐户(Google、Facebook 等)。
- 按指示扫描 QR 码。
在 “验证码 ”文本框中输入 TOTP 应用提供的验证码。
选择 “验证”。
成功验证后,页面会显示 验证器应用已验证 横幅和一些恢复代码。
在 VS Code 的 “SQL Server ”选项卡中,右键单击 RazorPagesPizza 数据库并选择“ 新建查询”。 输入以下查询,然后按 Ctrl+Shift+E 运行它。
SELECT FirstName, LastName, Email, TwoFactorEnabled FROM dbo.AspNetUsers
对于已登录用户,输出显示
TwoFactorEnabled
列等于1
。 由于没有为其他注册用户启用多重身份验证,因此记录的列值为0
。在 Web 应用中,选择 “注销”,然后使用同一用户再次登录。
在 Authenticator 代码 文本框中,输入 TOTP 验证器应用中的验证码。 选择“ 登录 ”按钮。
选择 你好,[名字] [姓氏]!。 然后,选择 “双因素身份验证 ”选项卡。
由于设置了 Microsoft Authenticator,因此将显示以下按钮:
- 禁用 2FA
- 重置恢复代码
- 设置验证器应用
- 重置验证器应用
在 VS Code 的终端窗格中,按 Ctrl+C 停止应用。
概要
在本单元中,你添加了向 “配置验证器”应用 表单生成 QR 码的功能。 在下一单元中,可以了解如何使用标识来存储声明并应用授权策略。