Wednesday, December 17, 2025

thumbnail

Implementing Two-Factor Authentication (2FA) in .NET Applications

 Implementing Two-Factor Authentication (2FA) in .NET Core Applications


Two-Factor Authentication (2FA) adds an extra layer of security to your application by requiring users to provide two forms of authentication before they can access their accounts. The first factor is typically a password (something the user knows), and the second factor is usually something the user has, such as a smartphone app (e.g., Google Authenticator) or an SMS code.


In ASP.NET Core, you can easily implement 2FA using ASP.NET Core Identity with built-in support for time-based one-time passwords (TOTP), which are commonly used in 2FA systems.


This guide will walk you through implementing 2FA in an ASP.NET Core MVC or Razor Pages application, including the necessary configurations and code.


1. Set Up ASP.NET Core Identity


If you're starting from scratch, make sure that ASP.NET Core Identity is set up for user authentication in your application. Identity handles user management, including login, registration, and 2FA functionality.


1.1. Install Required Packages


Make sure you have these NuGet packages installed for ASP.NET Core Identity:


dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore

dotnet add package Microsoft.EntityFrameworkCore.SqlServer

dotnet add package Microsoft.EntityFrameworkCore.Tools


1.2. Add Identity Services


In your Program.cs (or Startup.cs for older versions), configure ASP.NET Core Identity services.


public class Program

{

    public static void Main(string[] args)

    {

        CreateHostBuilder(args).Build().Run();

    }


    public static IHostBuilder CreateHostBuilder(string[] args) =>

        Host.CreateDefaultBuilder(args)

            .ConfigureWebHostDefaults(webBuilder =>

            {

                webBuilder.ConfigureServices((context, services) =>

                {

                    services.AddDbContext<ApplicationDbContext>(options =>

                        options.UseSqlServer(context.Configuration.GetConnectionString("DefaultConnection")));

                    services.AddDefaultIdentity<ApplicationUser>()

                        .AddEntityFrameworkStores<ApplicationDbContext>()

                        .AddDefaultTokenProviders(); // Add token providers for 2FA

                    services.AddRazorPages();

                    services.AddAuthentication();

                });

                webBuilder.Configure(app =>

                {

                    var env = app.Environment;

                    if (env.IsDevelopment())

                    {

                        app.UseDeveloperExceptionPage();

                    }

                    else

                    {

                        app.UseExceptionHandler("/Home/Error");

                        app.UseHsts();

                    }


                    app.UseHttpsRedirection();

                    app.UseStaticFiles();


                    app.UseRouting();


                    app.UseAuthentication();

                    app.UseAuthorization();


                    app.MapRazorPages();

                });

            });

}



Explanation:


AddDefaultTokenProviders() enables ASP.NET Core Identity to generate tokens for actions like email confirmation, password reset, and 2FA.


2. Enable Two-Factor Authentication (2FA)


Once Identity is set up, we can enable 2FA using a combination of Email, SMS, and Authenticator Apps (TOTP).


2.1. Configure 2FA in Startup.cs or Program.cs


Make sure 2FA is enabled for your Identity system by setting up the necessary token providers. This should already be configured when you call AddDefaultTokenProviders().


2.2. User Authentication and 2FA Setup


The next step is to allow users to configure 2FA. This involves setting up the ability for users to either receive 2FA codes via SMS or use TOTP (Authenticator Apps).


Configure TOTP (Authenticator App)


ASP.NET Core supports generating Time-based One-Time Passwords (TOTP) that work with authenticator apps such as Google Authenticator or Microsoft Authenticator.


Generate TOTP Key for User:

You will need to generate a QR code for users to scan with their authenticator app. This QR code is tied to a secret key.


Enable 2FA for User:

The user will enable 2FA during their login process or through their account settings.


3. Implementing 2FA (Authenticator App - TOTP)

3.1. Generate QR Code for Authenticator App


To generate a QR code for the user’s authenticator app, we will use the Totp feature of the Microsoft.AspNetCore.Identity library.


Add 2FA Setup Page: This is where the user will enable 2FA.


[HttpGet]

public async Task<IActionResult> EnableAuthenticator()

{

    var user = await _userManager.GetUserAsync(User);

    var model = new EnableAuthenticatorViewModel();


    // Generate a recovery code and QR code for the authenticator app

    var key = await _userManager.GetAuthenticatorKeyAsync(user);

    if (string.IsNullOrEmpty(key))

    {

        await _userManager.ResetAuthenticatorKeyAsync(user);

        key = await _userManager.GetAuthenticatorKeyAsync(user);

    }


    var qrCodeUrl = _urlEncoder.Encode($"otpauth://totp/MyApp:{user.UserName}?secret={key}&issuer=MyApp");


    model.QrCodeUrl = qrCodeUrl;

    model.SharedKey = key;


    return View(model);

}



In this code:


GetAuthenticatorKeyAsync generates a secret key for the user if they don't already have one.


ResetAuthenticatorKeyAsync is used to regenerate a new key if necessary.


qrCodeUrl is a URL that can be encoded into a QR code that users can scan using their authenticator app.


3.2. Generate QR Code Image


Once the QR code URL is generated, we can create an image for the user to scan using a QR code generation library like QRCoder.


Install the QRCoder package:


dotnet add package QRCoder



Then, in the EnableAuthenticator view:


public IActionResult EnableAuthenticator()

{

    var qrGenerator = new QRCodeGenerator();

    var qrCodeData = qrGenerator.CreateQrCode(model.QrCodeUrl, QRCodeGenerator.ECCLevel.Q);

    var qrCode = new QRCode(qrCodeData);

    using (var ms = new MemoryStream())

    {

        qrCode.GetGraphic(20).Save(ms, System.Drawing.Imaging.ImageFormat.Png);

        model.QrCodeImage = Convert.ToBase64String(ms.ToArray());

    }


    return View(model);

}



This generates the QR code image and returns it to the view in Base64 format.


3.3. Verify TOTP (Authenticator App) During Login


When the user logs in and has 2FA enabled, they'll be prompted to enter the TOTP code from their authenticator app. Here's how to verify the code:


[HttpPost]

[ValidateAntiForgeryToken]

public async Task<IActionResult> VerifyAuthenticatorCode(string code)

{

    var user = await _userManager.GetUserAsync(User);

    var isCodeValid = await _userManager.VerifyTwoFactorTokenAsync(user, _userManager.Options.Tokens.AuthenticatorTokenProvider, code);


    if (isCodeValid)

    {

        return RedirectToAction("Index", "Home");

    }


    ModelState.AddModelError(string.Empty, "Invalid code.");

    return View();

}



Here:


VerifyTwoFactorTokenAsync verifies the TOTP code entered by the user against the secret key.


4. Adding SMS-based Two-Factor Authentication


If you'd like to use SMS-based 2FA in addition to the authenticator app, you need to set up an SMS provider like Twilio or SendGrid.


4.1. Configure SMS Provider


Install Twilio or another SMS service provider.


dotnet add package Twilio



In your Startup.cs or Program.cs, configure the SMS provider:


public void ConfigureServices(IServiceCollection services)

{

    services.AddTransient<IUserTwoFactorTokenProvider<ApplicationUser>, SmsTokenProvider<ApplicationUser>>();

}


4.2. Sending SMS Codes


You will need to configure your application to send SMS codes using the SendSmsAsync method:


public class SmsTokenProvider : IUserTwoFactorTokenProvider<ApplicationUser>

{

    public async Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser> manager, ApplicationUser user)

    {

        var token = new Random().Next(100000, 999999).ToString();

        await SendSmsAsync(user.PhoneNumber, token);

        return token;

    }


    public Task<bool> ValidateAsync(string purpose, string token, UserManager<ApplicationUser> manager, ApplicationUser user)

    {

        return Task.FromResult(token == expectedToken);  // Compare token sent vs received

    }


    private async Task SendSmsAsync(string phoneNumber, string token)

    {

        // Integrate with your SMS service, e.g., Twilio

        var message = $"Your verification code is {token}";

        await _smsService.SendSmsAsync(phoneNumber, message);

    }

}



Here, the SmsTokenProvider generates a random code and sends it via SMS to the user’s registered phone number.


5. Handling 2FA Recovery Codes


For users who lose access to their second factor (phone, authenticator app), you should provide recovery codes that they can use to regain access to their account. These recovery codes are one-time-use codes that can be generated and stored securely.

Learn Dot Net Course in Hyderabad

Read More

Role-Based Access Control (RBAC) in .NET Core Applications

Preventing SQL Injection Attacks in Full Stack .NET Development

How to Protect Against Cross-Site Scripting (XSS) in ASP.NET Core

Implementing SSL/TLS in Full Stack .NET Applications

Visit Our Quality Thought Institute in Hyderabad

Get Directions 

Subscribe by Email

Follow Updates Articles from This Blog via Email

No Comments

About

Search This Blog

Powered by Blogger.

Blog Archive