練習 - 設定多重要素驗證
在上一個單元中,您已了解 ASP.NET Core 身分識別如何實作時間型單次密碼 (TOTP),以進行多重要素驗證 (MFA)。 在此單元中,您將自訂現有的 [設定驗證器應用程式] 表單,以提供包含註冊金鑰的 QR 代碼。
產生 QR 代碼
有多個策略可產生 QR 代碼。 本文件中的範例使用 client-side JavaScript library。 不過,在此單元中,會使用協力廠商 NuGet 套件,在伺服器上使用 C# 產生 QR 代碼。 產生的 QR 代碼影像會插入 HTML 預留位置元素中,作為 base-64 編碼的字串。
新增 QR 代碼服務
請建置您在設定驗證器應用程式表單上產生 QR 代碼所需的一切。
在終端窗格中,安裝
QRCoder
NuGet 套件:dotnet add package QRCoder --version 1.6.0
在 [Explorer] 窗格中,用滑鼠右鍵按一下 [服務] 資料夾,並新增名為 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
建置並執行應用程式。如果您尚未登入,請瀏覽至網站,並使用任何一個已註冊的使用者登入。 選取 [名字] [姓氏] 您好!連結以導覽至設定檔管理頁面,然後選取 [雙重要素驗證]。
選取 [新增驗證器應用程式] 按鈕。
依照畫面上的指示,為此使用者註冊並驗證您的驗證器應用程式。
使用 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 應用程式中,選取 [登出],然後使用相同的使用者重新登入。
在 [驗證器代碼] 文字方塊中,輸入 TOTP 驗證器應用程式的驗證碼。 選取 [登入] 按鈕。
選取 Hello, [First name] [Last name]!。 接著,選取 [雙重要素驗證] 索引標籤。
因為Microsoft Authenticator 已設定,因此會出現下列按鈕:
- 停用 2FA
- 重設復原碼
- 設定驗證器應用程式
- 重設驗證器應用程式
在 VS Code 的終端窗格中,按 Ctrl+C 以停止應用程式。
摘要
在此單元中,您已在設定驗證器應用程式表單中新增了產生 QR 代碼的功能。 在下一個單元中,您將了解如何使用 Identity 來儲存宣告並套用授權原則。