Setting Up Two-Factor Authentication In ASP.NET Core 2.0

In this article, I’m going to write a bit about security aspects in ASP.NET Core 2.0.

Whenever you create a new ASP.NET Core application, you will notice that there is an option on the dialog with a button captioned Change Authentication, and once you click on that, you will land upon a dialog having the below 4 options.

ASP.NET Core

I’ll discuss each of these options in detail but as of now, to get started, let’s take a high-level idea about these.
  • No Authentication – This means the application is completely anonymous and open for everyone to access it.
  • Individual User Accounts – It uses a local database for storing the information related to the user.
  • Work or School Accounts – It means the application will work with Office365, Active Directory, support for cloud, etc..
  • Windows Authentication – For internet applications, it and uses IIS capabilities to know who has logged in.
Here, I’ll be choosing my option as ‘Individual User Accounts’ which is very easy as well as common, with the sub-option chosen as ‘Store user accounts in-app’.

Once you click OK, you will notice that ASP.NET Core has added the required middleware in ConfigureServices method with a default token provider, as shown below.
  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddDbContext < ApplicationDbContext > (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));  
  3.     services.AddIdentity < ApplicationUser, IdentityRole > ().AddEntityFrameworkStores < ApplicationDbContext > ().AddDefaultTokenProviders();  
  4.     services.AddMvc().AddRazorPagesOptions(options => {  
  5.         options.Conventions.AuthorizeFolder("/Account/Manage");  
  6.         options.Conventions.AuthorizePage("/Account/Logout");  
  7.     });  
  8.     services.AddSingleton < IEmailSender, EmailSender > ();  
  9. }  
And in Configure method, the same is added to the HTTP request pipeline by calling UseAuthentication method, as shown below.
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  2.     if (env.IsDevelopment()) {  
  3.         app.UseBrowserLink();  
  4.         app.UseDeveloperExceptionPage();  
  5.         app.UseDatabaseErrorPage();  
  6.     } else {  
  7.         app.UseExceptionHandler("/Error");  
  8.     }  
  9.     app.UseStaticFiles();  
  10.     app.UseAuthentication();  
  11.     app.UseMvc();  
  12. }  
Does middleware configuration sequencing matter?

One important thing to notice in the above code snippet is the sequence in which middleware are configured. app.UserAuthentication is called after app.StaticFiles, which means we don’t want any of our static contents to be authenticated before rendering them on to the browser. 

Are you thinking, why? Well, let’s understand this with a common example of the Login page.

Login page usually has static contents like css, image, etc. If we shuffle the sequence of both the statements, then the Login page will never ever come until the user is authenticated. Now, if the user is already authenticated, then why do we need Login page? Isn’t it an interesting analogy?

What happens on click of Register?

Now, quickly run the application and click on Register and register yourself, as shown below:

ASP.NET Core
 
Once you populate the details and click on Register, you will land upon the below page.

ASP.NET Core
Nothing to worry about.

This is the expected behavior because our identity data is not stored anywhere. So, we have to create the required tables and for that, we can use local SQL Express database. This can be done quickly by pressing a button Apply Migrations as shown in the above screenshot. Once the button is pressed, just refresh your page and you would be happy to see the web page with your email id and Log out option in the top right corner, as shown below.

ASP.NET Core  

Configuring the registered data

Let’s say now if we want to modify our existing authentication details. So, to do that, one can click on mail id shown on the top right corner of the web page and that will land upon the below screen.

ASP.NET Core

So, in the above screen, we can change the registered email id, password and can also configure two-factor authentication.

Setting up two-factor authentication

Once you selected two-factor authentication in the above screen, you will be asked to add authenticator app, as shown below.

ASP.NET Core
 
Once the button is clicked, we will be taken to a page which will tell us that use the given key davi e4jo yiyt kmkz gtn5 jdek jmmb jpl5 as a password. Please note, this is the key generated for me. For you, it would be a different one.

But typing this key manually in a phone could be a very tedious process. Isn’t it?

So, other way to get the same information on the phone is by using the QR code. You can also see a hyperlink which will take you to a very nice documentation explaining about the steps on how to proceed.

Here we have to use JavaScript library for QR code generation. So, let’s quickly add that to our application under folder wwwroot/lib/qrCode.

Next is to call the method which will generate the QR code for us. Go to EnableAuthenticator.cshtml and update @section Scripts with below code,
  1. @section Scripts {  
  2.     @await Html.PartialAsync("_ValidationScriptsPartial") < script type = "text/javascript"  
  3.     src = "~/lib/qrCode/qrcode.js" >   
  4.       < /script>   
  5.       < script type = "text/javascript" >  
  6.         new QRCode(document.getElementById("qrCode"),   
  7.     {  
  8.         text: "@Html.Raw(Model.AuthenticatorUri)",  
  9.         width: 150,  
  10.         height: 150  
  11.     });   
  12. < /script>  
Make sure that path of qrcode.js is mentioned correctly. We are almost done. Now quickly launch the application and navigate back to Two-factor authentication tab. You will notice that nice QR code is ready for your scan as shown below,
 
ASP.NET Core  

Using Test Online Authenticator App

Now we have setup the two-factor authentication. In order to verify if it’s working correctly or not, we can use online authenticator app from URL: https://gauth.apps.gbraad.nl/.

Steps to use this application are.

Give some account name and give your key as a secret key and press Add. As soon as you will click on Add, some 6-digit number will be generated as shown below.
 
ASP.NET Core  
 
We will use this 6-digit number  to verify our authentication as shown below,

ASP.NET Core  

Quickly click on the Verify button and we are done with setting up our 2FA as shown below,

ASP.NET Core  

Using Recovery Codes

In the previous screenshot, you must have seen that some numbers are displayed in red color. Those numbers are called recovery code which are very useful in case you lose your phone or say you got a new phone. One should keep these keys in some secure place. Let’s have a look at how to use these recovery codes.

Launch your application and supply user name and password. On supplying correct details, you will be asked for Authentication Key as shown below,
ASP.NET Core

Now, click on the given hyperlink ‘log in with recovery code.’ which will further ask you to enter your recovery code. Pick any one of the recovery keys which were generated for you and enter in the given text box as shown below,

ASP.NET Core  
As soon as you will click on Login button, you will see that you are logged in. Aren’t you happy, even after losing your phone ๐Ÿ˜‰.
Now, 2FA is perfectly set up, you can go and reset your recovery code anytime.

Please note, any recovery code which was generated can be used only once but one can generate a recovery code any number of times.

Hope you enjoyed learning!