ASP.NET Core 3.1 - 2FA QR Code Generator
Download KH Authenticator

.NET MAUI App for Windows and Android
Online Registration and Authentication
No Password Or Email Address Required!
Certified Providers
KenHaggerty.Com Users Without Passwords Users With Passwords Users Without IdentityThis article will demonstrate the implementation of qrcode.js to display the 2FA authenticator key in a QR Code formatted image. I will assume you have downloaded the ASP.NET Core 3.1 - Users Without Identity Project or created a new ASP.NET Core 3.1 Razor Pages project. See Tutorial: Get started with Razor Pages in ASP.NET Core. You should review the earlier articles of the Users Without Identity Project series.
Users Without Identity Project and Article Series
Creation Series
- ASP.NET Core 3.1 - Users Without Identity
- ASP.NET Core 3.1 - User Entity
- ASP.NET Core 3.1 - Password Hasher
- ASP.NET Core 3.1 - User Management
- ASP.NET Core 3.1 - Admin Role
- ASP.NET Core 3.1 - Cookie Validator
- ASP.NET Core 3.1 - Concurrency Conflicts
- ASP.NET Core 3.1 - Must Change Password
- ASP.NET Core 3.1 - User Database Service
- ASP.NET Core 3.1 - Rename Related Entities
2FA Series
- ASP.NET Core 3.1 - 2FA Without Identity
- ASP.NET Core 3.1 - 2FA User Tokens
- ASP.NET Core 3.1 - 2FA Cookie Schemes
- ASP.NET Core 3.1 - 2FA Authenticating
- ASP.NET Core 3.1 - 2FA Sign In Service
- ASP.NET Core 3.1 - 2FA QR Code Generator
- ASP.NET Core 3.1 - Admin 2FA Requirement
- ASP.NET Core 3.1 - 2FA Admin Override
Enhanced User Series
- ASP.NET Core 3.1 - Enhanced User Without Identity
- ASP.NET Core 3.1 - 2FA Recovery Codes
- ASP.NET Core 3.1 - Login Lockout
- ASP.NET Core 3.1 - Created And Last Login Date
- ASP.NET Core 3.1 - Security Stamp
- ASP.NET Core 3.1 - Token Service
- ASP.NET Core 3.1 - Confirmed Email Address
- ASP.NET Core 3.1 - Password Recovery
The ASP.NET Core Identity UI displays the authenticator key as text. I implemented qrcode.js complete with CDN link and integrity check to display the key in a QR Code formatted image. Mobile authenticator apps can use the image and the phone's camera to input the key.
The EnableAuthenticator page from the scaffolded Identity UI uses a method, LoadSharedKeyAndQrCodeUriAsync to format the key and the QR Code Uri. Notice the page property, AuthenticatorUri is set with the QR Code Uri.
See EnableAuthenticator.cshtml.cs:
private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; private async Task LoadSharedKeyAndQrCodeUriAsync(AppUser user) { // Load the authenticator key & QR code URI to display on the form var unformattedKey = await _userService.GetAuthenticatorKeyAsync(user.Id); if (string.IsNullOrEmpty(unformattedKey)) { await _userService.ResetAuthenticatorKeyAsync(user.Id); unformattedKey = await _userService.GetAuthenticatorKeyAsync(user.Id); } SharedKey = FormatKey(unformattedKey); var name = User.FindFirst(ClaimTypes.Name).Value; AuthenticatorUri = GenerateQrCodeUri(name, unformattedKey); } private string FormatKey(string unformattedKey) { var result = new StringBuilder(); int currentPosition = 0; while (currentPosition + 4 < unformattedKey.Length) { result.Append(unformattedKey.Substring(currentPosition, 4)).Append(" "); currentPosition += 4; } if (currentPosition < unformattedKey.Length) result.Append(unformattedKey.Substring(currentPosition)); return result.ToString().ToLowerInvariant(); } private string GenerateQrCodeUri(string name, string unformattedKey) { return string.Format(AuthenticatorUriFormat, _urlEncoder.Encode("Users Without Identity"), _urlEncoder.Encode(name), unformattedKey); }
Add qrcode.js to libman.json. See ASP.NET Core 2.2 - Manage Client-Side Libraries
Edit libman.json:
{ "destination": "wwwroot/lib/qrcode/", "files": [ "qrcode.js", "qrcode.min.js" ], "library": "qrcodejs@1.0.0" }
Add the CDN link for qrcode.js to the EnableAuthenticator page.
<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js" asp-fallback-src="~/lib/qrcode/qrcode.min.js" asp-fallback-test="window.QRCode" integrity="sha512-CNgIRecGo7nphbeZ04Sc13ka07paqdeTu0WR1IM4kNcpmBAUSHSQX0FslNhTDadL4O5SAGapGt4FodqL8My0mA==" crossorigin="anonymous"> </script>
The EnableAuthenticator page uses a div to display the image.
<div id="qrCode"></div>
Use JavaScript on the page to configure the size and load the image.
<script> new QRCode(document.getElementById("qrCode"), { text: "@@Html.Raw(Model.AuthenticatorUri)", width: 200, height: 200 }); </script>
Update 02/23/2021
I added the Enhanced User Series' article links.
Comments(0)