Setting up QR Codes for ASP.Net Core 8 MFA

If you want more tips on ASP.Net Core security, take a look at my Pluralsight course here :

Pluralsight: Secure Coding in ASP.NET Core

ASP.Net Core allows you to create some great, secure by default authentication for your website. A key part of security is Multi-Factor Authentication (MFA). By default, it almost allows you to setup MFA using scaffolding, the only piece missing is the setup of a QR code so you can use MFA from your cell/mobile phone. Here's how to set that up in Visual Studio.

If you use OWASP ASVS as a basis for some of your application security then this covers "V2.8 One Time Verifier" of ASVS version 4.03 up to level 2.

You can find the finished code here: https://github.com/gavjl/ASP.Net-Core-Security-Examples/tree/main/ASP.NetCore8/QrCode

Starting Point

First, we're starting from a fresh ASP.Net Core 8 Web App (MVC View-Model) that's just been setup in Visual Studio.

Getting the Right Packages

Then, in Package Manager, we want to run the following commands:

dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Sqlite
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.DotNet.Scaffolding.Shared
dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Identity.UI
dotnet add package Microsoft.EntityFrameworkCore.Tools

Note that we're going to run this with a SQLite database to keep it simple. You can see that referenced above and in later commands.

Adding Identity Scaffolding

Now we want some scaffolding for our identity pages, we're setting up quite a few here, they're not all MFA specific:

dotnet aspnet-codegenerator identity --files "Account.Register;Account.Login;Account.Logout;Account.RegisterConfirmation;Account.ResetPassword;Account.ResetPasswordConfirmation;Account.Manage.Disable2fa;Account.Manage.TwoFactorAuthentication;Account.Manage.EnableAuthenticator" --databaseProvider sqlite

Creating Database Structure

With that, we need some database structure, so with Entity Framework:

dotnet-ef migrations add Identity
dotnet-ef database update

In Views/Shared/_Layout.cshtml, we want a link to the login page with the _LoginPartial:

Adding the login partial so the login menu is visible
<partial name="_LoginPartial" />

Map Razor Pages to Allow Use

Now, in Program.cs, we need to MapRazorPages so that all of the scaffolding will actually do something:

Mapping razor pages in Program,cs
app.MapRazorPages()

At this point you can:

  • start the application
  • register a new user (top right menu of the web app)
  • login as the registered user
  • Click your username (top right) to manage your account
  • Select Two-factor authentication
  • Click "Add authenticator app"
The manage account screen
The Two-factor authentication menu

This will show the following page:

The string of QR code information, but missing an actual QR code

But at this stage, it doesn't have a QR code, all it has is a string of characters that would be used by a QR code.

Generating a QR Code Image

Now, navigate to : https://github.com/davidshimjs/qrcodejs/blob/master/qrcode.js and copy that JavaScript into a new file called at wwwroot/js/qrcode.js

Create mfa.js in the same directory, so wwwroot/js/mfa.js and add some code to generate your QR code based on that string of characters, which is the value contained in the field with an ID of "qrCode" :

window.addEventListener("load", () => {
    const uri = document.getElementById("qrCodeData").getAttribute('data-url');
    new QRCode(document.getElementById("qrCode"),
    {
        text: uri,
        width: 256,
        height: 256
    });
});

Your wwwroot directory should look something like this:

Code in mfa.js to display the QR code

Set the App Name to Appear in the Authenticator App

In Areas/identity/pages/account/manage/EnableAuthenticator.cshtml.cs, you'll want to change the string "Microsoft.AspNetCore.Identity.UI" to be something relevant to your application, here I've used MyWebsiteName:

Replacing Microsoft.AspNetCore.Identity.UI with MyWebsiteName

Include our New JavaScript Files

In Areas/identity/pages/account/manage/EnableAuthenticator.cshtml we need to add the two JavaScript files that we're using:

adding the qrcode and MFA JavaScript
    <script type="text/javascript" src="~/js/qrcode.js"></script>
    <script type="text/javascript" src="~/js/mfa.js"></script>

Also remove the following HTML that gives information about setting up a QR code:

<div class="alert alert-info">Learn how to <a href="https://go.microsoft.com/fwlink/?Linkid=852423">enable QR code generation</a>.</div>
"Learn how to" string to be deleted

Now that you're finished...

That's it, now:

  • run the application
  • login
  • Click your username (top right) to manage your account
  • Select Two-factor authentication
  • Click "Set up authenticator app"

You can now scan that QR code with a mobile MFA application such as Google Authenticator or the Microsoft authenticator and it'll store your QR code for use later!

Logging out and back in will force the user to enter the 6 digit code from the MFA application before login completes.

Screen requesting MFA code during login

Now the supporting video: