Two Factor Google Authenticator Using ASP.NET Core And Angular

Introduction

Google Authenticator is a free security application that generates unique codes for two-factor authentication (2FA) purposes. 2FA is an added layer of security used to verify a user's identity by requiring them to provide two pieces of evidence: something they know (such as a password) and something they have (such as a smartphone).

The Google Authenticator app generates a time-based one-time password (TOTP) valid for a short period, typically 30 seconds. This code can be used as the second factor in a 2FA setup, along with a password or other first factor.

To use Google Authenticator, you must first enable 2FA on your account or app. Then, download and install the Google Authenticator app on your smartphone or tablet. When you log in to your account or app, you will be prompted to enter the unique code generated by the app along with your password. This ensures that even if someone knows your password, they cannot log in without access to the second-factor code generated by the Google Authenticator app.

Overall, 2FA adds an extra layer of security to your online accounts and helps protect you against various online attacks, such as phishing and password theft.

To implement 2-Factor Google Authenticator using ASP Net Core and Angular, you can follow the below steps.

Step 1. Install the Google Authenticator NuGet package.

Install-Package GoogleAuthenticator

Step 2. In the Asp Net Core application, create a class named "TwoFactorAuthenticatorService" and add the following code.

using Google.Authenticator;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class TwoFactorAuthenticatorService
{
    public string GenerateQrCodeUri(string email, string secretKey)
    {
        var tfa = new TwoFactorAuthenticator();
        return tfa.GenerateQrCodeUri(email, secretKey);
    }
    public bool ValidateTwoFactorPin(string secretKey, string twoFactorCode)
    {
        var tfa = new TwoFactorAuthenticator();
        return tfa.ValidateTwoFactorPIN(secretKey, twoFactorCode);
    }
    public string GenerateNewSecretKey()
    {
        var tfa = new TwoFactorAuthenticator();
        var setupCode = tfa.GenerateSetupCode("My App", "My User", "mysecretkey", 300, 300);
        return setupCode.Secret;
    }
}

Step 3. In the Angular application, create a component named "TwoFactorAuthenticatorComponent" and add the following code.

import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
  selector: 'app-two-factor-authenticator',
  templateUrl: './two-factor-authenticator.component.html',
  styleUrls: ['./two-factor-authenticator.component.css']
})
export class TwoFactorAuthenticatorComponent {
  email: string;
  secretKey: string;
  qrCode: string;
  twoFactorCode: string;
  constructor(private http: HttpClient) { }
  generateSecretKey() {
    this.http.get('/api/twofactorauthenticator/generatesecretkey').subscribe((result: any) => {
      this.secretKey = result;
      this.qrCode = 'https://chart.googleapis.com/chart?chs=300x300&chld=M|0&cht=qr&chl=' + encodeURIComponent(result);
    });
  }
  validateTwoFactorCode() {
    this.http.post('/api/twofactorauthenticator/validatetwofactorcode', { secretKey: this.secretKey, twoFactorCode: this.twoFactorCode }).subscribe((result: any) => {
      if (result) {
        alert('Valid code!');
      } else {
        alert('Invalid code!');
      }
    });
  }
}

Step 4. In the Angular application, create a template for the "TwoFactorAuthenticatorComponent" component and add the following code.

<div>
  <label>Email:</label>
  <input type="text" [(ngModel)]="email">
</div>
<div>
  <button (click)="generateSecretKey()">Generate Secret Key</button>
</div>
<div *ngIf="secretKey">
  <img [src]="qrCode">
  <p>Secret Key: {{ secretKey }}</p>
</div>
<div>
  <label>Two Factor Code:</label>
  <input type="text" [(ngModel)]="twoFactorCode">
  <button (click)="validateTwoFactorCode()">Validate Two Factor Code</button>
</div>

Step 5. In the Asp Net Core application, create a controller named "TwoFactorAuthenticatorController" and add the following code.

using Microsoft.AspNetCore.Mvc;
using QRCoder;
using System;
using System.Drawing;
using TwoFactorAuthenticator;
namespace YourNamespace.Controllers
{
    public class TwoFactorAuthenticatorController : Controller
    {
        // Action method to generate the QR code for the user to scan and set up their Two-Factor Authentication
        public IActionResult GenerateQRCode()
        {
            // Generate the Two-Factor Authentication secret key
            var secretKey = new Base32Encoder().Encode(Encoding.ASCII.GetBytes(Guid.NewGuid().ToString().Replace("-", "").Substring(0, 10)));           
            // Generate the QR code for the user to scan
            var qrCodeGenerator = new QRCodeGenerator();
            var qrCodeData = qrCodeGenerator.CreateQrCode($"otpauth://totp/YourAppName:YourUserName?secret={secretKey}&issuer=YourAppName", QRCodeGenerator.ECCLevel.Q);
            var qrCode = new QRCode(qrCodeData);
            var qrCodeImage = qrCode.GetGraphic(20);

            // Return the QR code image to the user
            return File(qrCodeImage, "image/png");
        }
        // Action method to verify the user's Two-Factor Authentication code
        [HttpPost]
        public IActionResult VerifyCode(string code)
        {
            // Get the user's Two-Factor Authentication secret key from the database or other storage location
            var secretKey = "yourSecretKey";
            // Verify the One-Time Password (OTP) entered by the user
            var tfa = new TwoFactorAuthenticator();
            var result = tfa.ValidateTwoFactorPIN(secretKey, code);
            // If the OTP is valid, redirect the user to their account or other authorized page
            if (result)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                // If the OTP is invalid, return an error message to the user
                ModelState.AddModelError("code", "The code entered is invalid.");
                return View();
            }
        }
    }
}

Summary

This article discusses the implementation of a 2-Factor Google Authenticator using ASP Net Core and Angular in detail.