Setting up QR Codes for ASP.Net Core 8 MFA
Adding a scannable QR code image to your ASP.Net Core 8 website
![Setting up QR Codes for ASP.Net Core 8 MFA](/content/images/size/w2000/2024/06/Header-2.jpeg)
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
Create Links for Login
In Views/Shared/_Layout.cshtml, we want a link to the login page with the _LoginPartial:
![](https://gavinjl.ghost.io/content/images/2024/05/AddLoginPartial.png)
<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:
![](https://gavinjl.ghost.io/content/images/2024/05/AddMapRazorPages.png)
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"
![](https://gavinjl.ghost.io/content/images/2024/05/ManageAccount.png)
![](https://gavinjl.ghost.io/content/images/2024/05/AddAuthenticatorApp.png)
This will show the following page:
![](https://gavinjl.ghost.io/content/images/2024/05/AuthenticatorString.png)
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:
![](https://gavinjl.ghost.io/content/images/2024/05/mfa.js.png)
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:
![](https://gavinjl.ghost.io/content/images/2024/05/MyWebsiteName.png)
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:
![](https://gavinjl.ghost.io/content/images/2024/05/AddScripts.png)
<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>
![](https://gavinjl.ghost.io/content/images/2024/05/RemoveLearnHowTo.png)
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.
![](https://gavinjl.ghost.io/content/images/2024/05/MfaLogin.png)
Now the supporting video:
Got a comment or correction (I’m not perfect) for this post? Please leave a comment below.
Subscribe to Gavin Johnson-Lynn
Get the latest posts delivered right to your inbox