This post was going to be an update of the SMS using Twilio Rest API in ASP.NET Core post a made a year or so ago, but once I got the example project created I noticed that the default template has removed SMS as an option for two-factor authentication in favor of authenticator auth support.
This post is going to explore the setup of this new two-factor authentication style. In a follow-up post, I may look at adding back support for SMS as the second factor as that seems like a more common scenario albeit a less secure one.
Project Setup
To create a new Razor Pages application using individual authentication I used the following command from a command prompt. Make sure you are in the directory you want the files to end up. The only reason I mention this is I just spend the last 5 minutes cleaning up my user directory because I forgot to change directories.
dotnet new razor --auth Individual
Next, I move up a directory and used the following command to add a new solution file.
dotnet new sln -n TwoFactorAuth
Finally, I used the following command to add the new project to the solution file. If you aren’t using Visual Studio then you don’t have to have the solution file.
dotnet sln add TwoFactorAuth\TwoFactorAuth.csproj
The project after the above can be found here.
Add a QR Code
Strictly speaking, a QR code isn’t required, but it is much better for users so they don’t have to enter a 32 character key into their authenticator application manually. I followed the official docs to enable QR code generation.
The first step is to download a Javascript QR Code library. I just used the one recommended in the docs, but any would work. This link will take you to a zip download. Open the download and copy qrcode.js and qrcode.min.js into a new qrcode directory inside of your project’s wwwroot/lib/ directory.
Next, find your project’s EnableAuthenticator.cshtml file and update the scripts section at the bottom of the page to the following.
@section Scripts { @await Html.PartialAsync("_ValidationScriptsPartial") <script type="text/javascript" src="~/lib/qrcode/qrcode.js"></script> <script type="text/javascript"> new QRCode(document.getElementById("qrCode"), { text: "@Html.Raw(Model.AuthenticatorUri)", width: 150, height: 150 }); </script>
Enabling Two-Factor Authentication
The above changes are all that is required, and now we are going to walk through what it looks like for the user. Once logged in click on your user in in the upper right after of the site to open user management.
Next, click the Two-factor authentication link.
Then, click Configure authenticator app link.
This will land you on the page with the QR code.
Now using the authenticator application of your choice you can scan the QR code. Once scanned your authenticator application will display a code. Enter the code in the Verification Code box and click Verify. If all goes well you will be taken to a page that lists a set of recovery code for use if you can’t use your authenticator application for some reason.
Wrapping Up
I think it is awesome how easy the ASP.NET Core team has made the use two-factor authentication. With this being built into the templates it pushes all in the right direction. I do wish they would have left SMS as an option, but hopefully, it wouldn’t be hard to put back in.
The code in the final state can be found here.
Also published on Medium.
Great post Eric. I think the recovery codes are new – I cannot remember that that was there before.
BTW, try and stay away from SMS for 2FA as it is insecure. Google “sms 2fa” and you can find many articles related to it.
Thank you, Jerrie! This feature was added as part of the 2.0 release.
I 100% agree that SMS isn’t a great option. I just imagine my parents trying to use an authenticator application and I don’t see it working very well if at all. Given the authenticator, applications have gotten much better.
I hope this is a space we continue to see progress in. This is definitely not a solved problem.
I have a minor comment and problem. When I follow the steps outlined and go to register a user I get a page that indicates that the application failed. I am guessing that it is because I didn’t run the migrations in the project. There isn’t an option to “Apply Migrations” as there was before. What should I use now?
You can use the dotnet cli to update the database. Try checking out dotnet ef -h
Looking further into the problem it seems the database has been created (I went into the PM console and entered Update-Database) as I can see the database with SSMS and the .mdf and .ldf files in my home directory (I augmented the calls you specified with –use-local-db rather than the default of SQLite).
What is the error you are getting? Normally it will give you at least a little hint. You could also try deleting the database and see if it will recreate the database.
Hi,
After QR code scanned, the key generated from Authenticator is not accepted by application.
I’ve tried with both google/microsoft authenticator.
It throws false in ‘await _userManager.VerifyTwoFactorTokenAsync()’ condition
I’ve used your github sample code and not changed any code.
Please let me know any other changes have to do in the application.
Hey Saravanan! All the changes I had to make to get it to work are in this post. Does it work if you manually enter the code instead of scanning the QR code?
Hello Saravanan,
I am facing the same issue as you.
Were you able to solve it? If yes, would you mind sharing some info? :)
Thanks!