Edit

Share via


Enable QR code generation for TOTP authenticator apps in an ASP.NET Core Blazor Web App

Note

This isn't the latest version of this article. For the current release, see the .NET 9 version of this article.

Important

This information relates to a pre-release product that may be substantially modified before it's commercially released. Microsoft makes no warranties, express or implied, with respect to the information provided here.

For the current release, see the .NET 9 version of this article.

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 Enable QR code generation for TOTP authenticator apps in ASP.NET Core.

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 ASP.NET Core code generator tool (`aspnet-codegenerator`).

Warning

TOTP codes should be kept secret because they can be used to authenticate multiple times before they expire.

Adding QR codes to the 2FA configuration page

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.

Note

For guidance on adding packages to .NET apps, see the articles under Install and manage packages at Package consumption workflow (NuGet documentation). Confirm correct package versions at NuGet.org.

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 source

The EnableAuthenticator component can be inspected in reference source:

EnableAuthenticator component in reference source

Note

Documentation links to .NET reference source usually load the repository's default branch, which represents the current development for the next release of .NET. To select a tag for a specific release, use the Switch branches or tags dropdown list. For more information, see How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205).

Failures due to TOTP time skew

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.

Additional resources