aspnetcore/blazor/security/qrcodes-for-authenticator-apps.md
This article explains how to configure an ASP.NET Core Blazor Web App for two-factor authentication (2FA) with QR codes generated by Time-based One-time Password Algorithm (TOTP) authenticator apps.
For an introduction to 2FA with TOTP authenticator apps, see xref:security/authentication/identity-enable-qrcodes.
The guidance in this article relies upon either creating the app with Individual Accounts for the new app's Authentication type or scaffolding Identity into an existing app. For guidance on using the .NET CLI instead of Visual Studio for scaffolding Identity into an existing app, see xref:fundamentals/tools/dotnet-aspnet-codegenerator.
[!WARNING] TOTP codes should be kept secret because they can be used to authenticate multiple times before they expire.
A QR code generated by the app to set up 2FA with an TOTP authenticator app must be generated by a QR code library.
The guidance in this article uses manuelbl/QrCodeGenerator, but you can use any QR code generation library.
Add a package reference for the Net.Codecrete.QrCodeGenerator NuGet package.
Open the EnableAuthenticator component in the Components/Account/Pages/Manage folder. At the top of the file under the @page directive, add an @using directive for the QrCodeGenerator namespace:
@using Net.Codecrete.QrCodeGenerator
Delete the <div> element that contains the QR code instructions and the two <div> elements where the QR code should appear and where the QR code data is stored in the page:
- <div class="alert alert-info">
- Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable
- QR code generation</a>.
- </div>
- <div></div>
- <div data-url="@authenticatorUri"></div>
Replace the deleted elements with the following markup:
<div>
<svg xmlns="http://www.w3.org/2000/svg" height="300" width="300" stroke="none"
version="1.1" viewBox="0 0 50 50">
<rect width="300" height="300" fill="#ffffff" />
<path d="@svgGraphicsPath" fill="#000000" />
</svg>
</div>
Just inside the opening @code block, change the variable declaration for authenticatorUri to svgGraphicsPath:
- private string? authenticatorUri;
+ private string? svgGraphicsPath;
Change the site name in the GenerateQrCodeUri method. The default value is Microsoft.AspNetCore.Identity.UI. Change the value to a meaningful site name that users can identify easily in their authenticator app. Developers usually set a site name that matches the company's name. We recommend limiting the site name length to 30 characters or less to allow the site name to display on narrow mobile device screens.
In the following example, the default value Microsoft.AspNetCore.Identity.UI is changed to the company name Weyland-Yutani Corporation (©1986 20th Century Studios Aliens).
In the GenerateQrCodeUri method:
- UrlEncoder.Encode("Microsoft.AspNetCore.Identity.UI"),
+ UrlEncoder.Encode("Weyland-Yutani Corporation"),
At the bottom of the LoadSharedKeyAndQrCodeUriAsync method, add the var keyword to the line that sets authenticatorUri, making it an implicitly-typed local variable:
- authenticatorUri = GenerateQrCodeUri(email!, unformattedKey!);
+ var authenticatorUri = GenerateQrCodeUri(email!, unformattedKey!);
Add the following lines of code at the bottom of the LoadSharedKeyAndQrCodeUriAsync method:
var qr = QrCode.EncodeText(authenticatorUri, QrCode.Ecc.Medium);
svgGraphicsPath = qr.ToGraphicsPath();
Run the app and ensure that the QR code is scannable and that the code validates.
[!WARNING] An ASP.NET Core TOTP code should be kept secret because it can be used to authenticate successfully multiple times before it expires.
EnableAuthenticator component in reference sourceThe EnableAuthenticator component (Components/Account/Pages/Manage/EnableAuthenticator.razor in the server project) can be inspected in the Blazor Web App project template (dotnet/aspnetcore GitHub repository).
TOTP authentication depends on accurate time keeping on the TOTP authenticator app device and the app's host. TOTP tokens are only valid for 30 seconds. If logins are failing due to rejected TOTP codes, confirm accurate time is maintained, preferably synchronized to an accurate NTP service.