ASP.NET Core 3.1 - 2FA Without Identity

Ken Haggerty
Created 08/20/2020 - Updated 08/31/2020 06:28

This article introduces a series about implementing two-factor authentication without ASP.NET Core Identity. I will assume you have 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

Access to the research project source code may be purchased on KenHaggerty.Com at Manage > Assets. A project which implements users without Identity has been published to I enjoy writing these articles. It often enhances and clarifies my coding. The research project is a result of a lot of refactoring and hopefully provides logical segues for the articles. Thank you for supporting my efforts.

While quality testing and updating the Bootstrap Native Project's (BSNP) scaffolded Identity UI, I implemented a QR Code generator and developed copy and paste functions for authenticator app's keys and verification codes. See article: ASP.NET Core 3.1 - Copy and Paste. See live demo: Ken's Demo Site - Copy and Paste. ASP.NET Core Identity makes the two-factor authentication (2FA) implementation seem easy. This series will break down this complex implementation into key concepts.

User Tokens

The Users Without Identity Project (UWIP) implements AppUser, a minimal entity which is created by administrators who invite the user to login. The 2FA User Tokens article will describe the implementation of a TwoFactorEnabled property for the user and a related AppUserToken entity.

Cookie Schemes

The UWIP used the single CookieAuthenticationDefaults. AuthenticationScheme before I implemented 2FA cookie schemes like ASP.NET Core Identity. The 2FA Cookie Schemes article demonstrates the implementation of the ApplicationScheme, TwoFactorUserIdScheme, and TwoFactorRememberMeScheme cookie schemes.


You need to generate an authenticator key and verify the code provided by the authenticator app. Authenticator apps generate a time-based one-time password (TOTP). The TOTP is a 6 digit code which is a hash of the key and the current time. The authenticator key must use base 32 characters. To verify the TOTP you need to generate a code with the same algorithm and compare. The 2FA Authenticating article will describe this implementation in a TwoFactorAuth class.

Sign In Service

The UWIP used a simple AuthenticateUser function to to validate users before I implemented a SignInService class. If a user with 2FA enabled logs in with a valid login name and password, they are not immediately authenticated. The 2FA Sign In Service article describes using a PasswordSignInAsync function which returns a SignInResult indicating Succeeded, Failed, or RequiresTwoFactor. The SignInService also implements functions like SignOut, RefreshSignIn, and functions which remember and forget the current 2FA browser.

QR Code Generator

Identity UI displays the authenticator key as text. The QR Code Generator article will demonstrate the implementation of 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.

Admin 2FA Requirement

I implemented the 2FA requirement for administrators using ASP.NET Core Identity in the BSNP and without Identity in the UWIP. The Admin 2FA Requirement article will describe how to implement a requireAdmin2FA policy option and a custom 2FA enabled claim to deny access to admin pages for administrators who have not enabled 2FA.

Update 08/28/2020

I updated the series article links.

Update 08/31/2020

I added the 2FA Admin Override article link.

Comment Count = 0

Please log in to comment or follow.

Login Register
Follow to get web notifications when new comments are posted to this article.
Logged in users receive web notifications for new articles, topics and assets.
Web Notifications