Skip to content
Howard van Rooijen By Howard van Rooijen Co-Founder
Using the Playwright C# SDK to automate 2FA authentication for AAD and MSA

Two-Factor Authentication (2FA) is becoming a sensible default requirement for most organisations and web sites. This simple feature adds significant protection to users. The downside is that it causes significant complexity for anyone trying to implement UI Automation Tests where the second-factor requires human-intervention. We can solve this impasse by configuring AAD / MSA accounts with Time-based One-Time Passwords (TOTP), using OTP.NET and Playwright. A sample project is provided.

Playwright is an excellent cross-browser, cross-platform, cross-language modern web app testing framework. The C# SDK makes elegant use of async / await semantics to produce clean, easy to understand, reliable & resilient automation code. You can use Playwright in a console app or in a unit testing project (NUnit / MSTest).

Azure Weekly is a summary of the week's top Microsoft Azure news from AI to Availability Zones. Keep on top of all the latest Azure developments!

Getting started is as simple as adding a reference to the NuGet package Microsoft.Playwright and then you can open a Windows Terminal session, navigate to the root of your project and use the following command to spawn a browser and interaction recorder:

pwsh bin/Debug/net7.0/playwright.ps1 codegen
The best hour you can spend to refine your own data strategy and leverage the latest capabilities on Azure to accelerate your road map.

Your interaction with the web page are converted into C# using the Playwright SDK. It's an incredibly simple way to get started and create something useful.

The UI Automation Testing and 2FA Dilemma

In order to automate testing a web app that provides authentication using AAD or MSA account with 2FA, there are a couple of strategies you can take:

  • Create a dedicated test user
  • Configure your own account

The secret sauce to allow automation of 2FA is to enable Time-based One-Time Password (TOTP) on these accounts.

Configure your Azure Active Directory Account (AAD)

For AAD, use the following steps to get to the Authenticator App configuration screen. Rather than using the default option of the excellent Microsoft Authenticator App, you need to go down the path of manual configuration in order to access the Secret key that you can use to generate a TOTP.

  • Navigate to
  • Click "Add sign-in method"
  • Click "authenticator app"
  • Click the "I want to use a different authenticator app" link
  • Set up your account
  • Click the Next button
  • Click the "Can't scan image" button
  • Set up Auth app + save Secret key for later!

AAD 2FA configuration screen

The final step is to change your default 2FA method. In order to be able to fully automate the 2FA authentication process, you need to select "App based authentication or hardware token - code". This will allow you to enter a Time-based One-Time Password (TOTP) rather than perform a manual notification approval via a authenticator app.

Change Default Method screen

Configure your Microsoft Account (MSA)

If you use a Microsoft Account, the process is very similar. You need to follow the manual configuration process to access the Secret key:

  • Navigate to
  • Advanced security options
  • Add a new way to sign in or verify
  • Use an app
  • Set up a different authenticator app
  • Click the Next button
  • Click the "I can't scan the barcode" link
  • Set up Auth app + save Secret key for later!

MSA 2FA configuration screen

Using OTP.NET to generate a TOTP

OTP.NET makes it incredibly simple to use the Secret key to generate a Time-based One-Time Password (TOTP):

private static string GenerateTwoFactorAuthCode(string secret)
    Totp totp = new(secretKey: Base32Encoding.ToBytes(secret));
    return totp.ComputeTotp();

Configure Environment Variables

I've created a sample project that demonstrates how to automate authentication with 2FA with accounts configured as above using Playwrite and OTP.NET. In order to run the sample, you need to set the following Environment Variables:



Environment Variables

If you had Visual Studio open, you will need to restart it, and re-open the solution to access the new Environment Variables.

Programming C# 10 Book, by Ian Griffiths, published by O'Reilly Media, is now available to buy.

This approach could be adapted if you wanted to run this code within GitHub Actions where you'd store these values as Secrets. Alternatively you could store them in Azure Key Vault.

Demo Solution

You can find all the code in the repo in the endjin GitHub org

@HowardvRooijen | @endjin

Managing applications using Azure AD, service principals and managed identities: A permissions story

Managing applications using Azure AD, service principals and managed identities: A permissions story

Carmel Eve

The complexities around Azure Active Directory can be difficult to understand. This post runs through some of the key concepts - AAD apps, service principles, managed identities, and walks through an example of how to set some of this up!
Secure Azure Function-to-Function authentication without the need for credentials

Secure Azure Function-to-Function authentication without the need for credentials

Carmel Eve

Building a secure solution on Azure can be a daunting task. Using Azure Functions and Managed Identities, we have built up a pattern for giving services access to one another, without the need to store credentials. These managed identities can be given access to necessary resources. For example, they can be granted roles and added to access control lists in ADLS Gen2 accounts, or the ability to access keys in key vault. This means that data can be securely accessed without needing to store connection strings or app passwords.
A simple invite user flow for AAD B2C (without custom policies)

A simple invite user flow for AAD B2C (without custom policies)

James Broome

Azure AD B2C is easy to integrate and configure for simple sign-in / sign-up authentication. But there's a step change in complexity as soon as you want to do something outside of the built-in user flows. An "invite user" flow is one such example, but it's also a fairly common requirement in any business or team orientated SaaS application, which makes AAD B2C as less attractive choice. This post describes an alternative approach for this authentication feature that avoids the need for AAD B2C custom policies, allowing you to keep authentication as simple as possible.

Howard van Rooijen


Howard van Rooijen

Howard spent 10 years as a technology consultant helping some of the UK's best known organisations work smarter, before founding endjin in 2010. He's a Microsoft ScaleUp Mentor, and a Microsoft MVP for Azure and Developer Technologies, and helps small teams achieve big things using data, AI and Microsoft Azure.