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.
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.
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,
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
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.
I updated the series article links.
I added the 2FA Admin Override article link.