Adding two-factor authentication to ASP.NET

= Adding two-factor authentication to ASP.NET using Google Authenticator =

Description
If you wish to add two factor authentication to your ASP.NET site you can use ASP.NET's Microsoft's Identity Framework and Google's "Authenticator" app. A pre-prepared NuGet Package by Lachlan Barclay is available which contains all the code you need.

If you are adding two-factor authentication to an existing site or codebase, start by creating a brand new project and adding the already-prepared NuGet package. This will add all of the necessary code, web pages, references and dependencies. Once you have that working you can go ahead and add the code to your existing codebase.

Create your sample application
The first step is to create a new ASP.NET MVC web application, making sure to set authentication to none. (In this example I am creating a fictitious "Movie Manager" application". )



From this screen you can click “Ok” – and then on the next screen turn off authentication by clicking “Change Authentication” and selecting “No Authentication”:





You should now have a very basic MVC app:



Adding the NuGet package
You can now add the NuGet package “AddTwoFactorToMvc” by running the following command:

install-package AddTwoFactorToMvc



the following files and directories should have been added to your solution:

Directories Added
All of these files should be added to your source control system.

You should also see an installation/configuration page that will tell you how to get started. There are just three steps needed:


 * 1) Database Configuration
 * 2) SMTP Configuration
 * 3) Adding the Login Bar to your master page

Database Configuration
The first step will be to create a SQL Server DB that will be used to store the member’s credentials. You can do this very simply by using the following script:

CREATE DATABASE [moviemanager] GO

you will also need to create a user that your ASP.NET application uses to connect to the DB as:

USE [master] GO CREATE LOGIN [moviemanageruser] WITH PASSWORD=N'moviemanagerpassword', DEFAULT_DATABASE=[moviemanager], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO USE [moviemanager] GO CREATE USER [moviemanageruser] FOR LOGIN [moviemanageruser] GO ALTER ROLE [db_owner] ADD MEMBER [moviemanageruser] GO

You will need to add a connection string to your web.config:

...   

Once the tables have been created, we need to add the columns necessary for two factor authentication by running the following script file:

TwoFactor\database-scripts\update-existing-db.sql

Db Owner?
You may have noticed that we have added the db_owner role to the moviemanageruser account. This is a very bad practice when it comes to security, as it means that if someone can find a way to execute SQL via a security hole on your website, they will have full access to your entire DB. They can read your data, update your data, or worse of all, delete your entire database.

We need to give the user account full access so that the entity framework can do its thing and create all of the tables necessary. Once they have been set up, we can lower the permissions level needed. I will write another post on this soon.

Configuring SMTP
Whenever a user registers on your site, you need to send them an email so they can confirm that they own that email address. You’ll need to enter your SMTP server’s details so that this email can be sent. If you open this file you can edit the following file:

TwoFactor\classes\common\SendEmail.cs

With these contents:

namespace MovieManager {    public class Emailer {       const string smtpServerName = "localhost"; const string replyToEmail = "donotreply@yourcompany.com"; public void sendEmail(string email, string subject, string body) {            using (MailMessage mail = new MailMessage( replyToEmail, email, subject, body)) {                 mail.IsBodyHtml = true; using (SmtpClient client = new SmtpClient) {                    client.Port = 25; client.DeliveryMethod = SmtpDeliveryMethod.Network; client.Host = smtpServerName; client.Send(mail); }            }         }     } }

For development purposes you can simply comment out the client.send(mail), as you will be able to approve the registered email address manually.

Adding the Login Bar
You will also need to add the “Register / Login / Manage My Account” links to your site:



these have been bundled into a partial view named:

Views\Shared\LoginPartial.cshtml

which has been added to your project by the NuGet package. You’ll need to add a call to @Html.Partial to render it, which I suggest putting into your Views\Shared\_Layout.cshtml page:

...  @Html.Partial("_LoginPartial") ...

Testing
You can now go ahead and test your two factor authentication! Simply register on your site:



After you click “Register”, you will need to verify your email. If you are working on a Debug build, you can just click on the link provided which will verify your email automatically:



Your email should now be confirmed:



And you can now login:



voila!



Now you need to enable two factor authentication, just like an ordinary user would. Click on your user account:



and click “Enable” for google’s authenticator:



you will now need to scan the QR code using Google’s Authenticator app, and enter the 6 digits provided:



now log out, and log back in again, this time you should see the following:



enter the verification code shown on your mobile and you have successfully logged in!

Points To Note

 * 1) Your database user still has db_owner permission. You need to lower this.
 * 2) You need to encourage your users to use a complex password. You can add a “password strength meter”, using something like JQuery Password Strength Meter, or you can add links to KeePass &amp; LastPass.
 * 3) At no point is any data (password or otherwise) transferred to or from google’s servers. The joy of the authenticator app is that you are (essentially) storing a password on your mobile, and your application knows how to work out if the one-time 30 second code is currently valid. There is no need to transmit the password over the wire.
 * 4) Calling it "two factor authentication" is bad. Why? Most users see that phrase and go “I don’t know what that is, I’m not interested”. Calling it something like Login Approvals like facebook have is a much friendlier approach, and you will probably see much higher adoption!
 * 5) Adding functionality that says “you have recently logged in from a new/unknown device, if you don’t recognise it let us know” would be a great extra layer of security. A free system like MaxMind might be useful, or a paid system like IpInfo might help.
 * 6) If you are developing an internal enterprise system, training your users on basic security principles is definitely necessary. No sharing of passwords, lock your computer when you leave your desk, don’t plug in random USB sticks, etc etc.
 * 7) Protecting yourself from the top 10 most common security vulnerabilities will go a long way to making your app more secure. No point in adding 2FA if your site is very easily hacked.

Other References
Two factor Auth using SMS and Email with ASP.NET Identity Another take on Google Authenticator