Two-Factor Authentication with Authy, C# and ASP.NET MVC

Two-Factor Authentication (2FA) is an excellent addition to your web application to improve the security of your user data by requiring something your users have to be present for step-up transactions, log-ins, and other actions. Multi-factor authentication validates the identity of a user while logging into the app through their mobile device (or sometimes through other clients)

If you haven't already, now is the time to sign up for Authy with Twilio. Create your first application, naming it whatever you wish. After you create your application, your production API key will be visible on your Authy dashboard:

Once we have an Authy API key, we store it in the Web.config file. We also need to register Authy as a 2FA provider in our IdentityConfig.

When a new user signs up for our website, we call this controller to handle storing our new user in the database as well as registering the user with Authy.

All Authy needs to get a user set up for your application is the user email, phone number and country code. In order to do two-factor authentication, we need to make sure we ask for this information at sign up.

Once we register the User with Authy we get an authy_id back. This is very important since it's how we will verify the identity of our user with Authy.

When our user logs in, we let them decide which two-factor authentication provider will be used. It can be either Authy One Touch or Authy Token. Authy OneTouch should be used when the user has a registered OneTouch device.

Authy lets us pass details with our OneTouch request including a message, a logo, and any other details we want to send. We could easily send any number of details by appending details['some_detail']. You could imagine a scenario where we send a OneTouch request to approve a money transfer:

In order for our app to know what the user did after we sent the OneTouch request, we need to register a callback endpoint with Authy.

Note: In order to verify that the request is coming from Authy, we've written a helper method that will halt the request if it appears it isn't coming from Authy.

Here in our callback, we look the user up using the authy_id sent with the Authy POST request. At this point we would ideally use a websocket to let our client know that we received a response from Authy, but for this version we're going to keep it simple and just update the AuthyStatus on the user. Then all our client-side code needs to do is check for user.AuthyStatus == "approved" before logging in the user.

We've already taken a look at what's happening on the server side, so let's step in front of the cameras now and see how our JavaScript is interacting with those server endpoints.

When we expect a OneTouch response, we will begin polling /Authy/OneTouchStatus until we either see that OneTouch login was either approved or denied. Let's take a look at this controller and see what is happening.