Two-Factor Authentication (2FA)

Users can secure access to their app accounts with 2FA, which requires input of a verification code when signing in on the new devices.

Multi-Factor Authentication

A combination of a username and password provides access to the personalized features of applications. Unfortunately both elements of the online identity are the primary source of the security breaches. Username and password are obtained by perpetrators through social engineering attacks, spy programs, and other nefarious means. The complexity of our lives forces us to share the passwords with loved ones and friends. The robust mechanisms of online identity protection are urgently needed in every application.

Many organizations adopt security systems that require their users to enter a numeric time-based verification code generated by an authenticator app installed on the user’s mobile device. The unique secret key is associated with the user account in the application database. Authenticator app uses the same secret to generate a new verification code periodically and does not require a network interaction with the application. The server-side code generates the verification code in real time and compares it to the one provided by the user. If the correct verification code is not provided at the time of sign in, then the access to the application is not granted even if the user is entering the correct username and password combination.

The username, password, verification code in the text message or email, and the phone with the authenticator app with optional fingerprint scan or face recognition are the components of the multi-factor authentication.

2-Factor Authentication Setup

Applications created with Code On Time can force the end users to provide an additional piece of information to confirm their identity after the username and password were confirmed. By default, the 2-Factor Authentication is the opt-in feature. It can be enabled in the user context menu.

image22.png
The standard 2-Factor Authentication option is available in the user account menu by default. Users can opt-in to use this enhanced security feature.

The 2-Factor Authentication option is available to the authenticated user. The 2FA setup is not available to the end user if their identity is confirmed by an OAuth Identity Provider. Application will rely on the authentication verification methods of the provider instead.

The initial activation of 2FA will require the user to confirm their password.

image6.png
The prompt to re-enter the password is displayed to the authenticated user when the 2-Factor Authentication option is selected in the user account menu.

Next the user is giving their consent to enter a verification code after the successful sign in. By default two verification methods are pre-selected. Users may opt into getting a verification code via email or to use an authenticator app.

image18.png
The user consent is required to enable the 2-Factor Authentication. Users must also choose the verification code delivery methods, such as an authenticator app or email. At least one verification method must be selected.

The verification code delivery via email will rely on the email address associated with the user account. This is a less secure method than using an authenticator app since there may be other individuals who can read the user’s emails.

Choosing the more secure method of verification will present the user with the QR code that needs to be scanned in Google Authenticator, Microsoft Authenticator, or another similar app. The QR code includes the information about the secret associated with the user account, the name of the app, and the name of the user along with some additional configuration data.

image14.png
The best method of securing an application with the 2-Factor Authentication is an authenticator application. The QR code is displayed in the 2FA setup form to be scanned in the authenticator app preferred by the user.

Google Authenticator begins showing the verification code immediately after the scan of the QR code. The time code will change every 30 seconds. There is no need to write down the verification codes since they will not be usable in the future. Other authenticator apps have a similar user interface and may require a fingerprint scan or face recognition to display the verification codes. This provides true multi-factor authentication.

image7.png
The Google Authenticator app in the picture shows the verification code after the QR code was scanned in the 2-Factor Authentication setup form of an application created with Code On Time. The name of the app and the username are displayed above the code. This makes it easy to locate the verification code of a specific application.

If the user is not able to scan the QR code then they may opt to enter the setup key manually directly in the authenticator app.

image13.png
If the preferred authenticator app cannot scan the QR code, then the user has an option to enter the setup key manually.

Users may also indicate that they need help installing an authenticator app. Three authenticator app suggestions are offered by default. Scanning of the QR code with the camera of the mobile device will direct the user to the corresponding app store. Users must install the app and choose another option in the App Config to proceed with the 2-Factor Authentication setup.

image9.png
If the user does not have an authenticator app installed on their mobile device, then several options will be offered by default, which includes the Google Authenticator, Microsoft Authenticator, and Salesforce Authenticator. Scanning of the barcode with the device camera will reveal the link to the corresponding app store.

Users must press the Next button when their authenticator app account is configured through the QR code scan or after the direct input of the setup key.

The configuration screen will present the list of the “single use” backup codes. The backup codes are also available for the other verification methods including email, text message, and call.

image11.png
Users must save and print the single-use backup codes. These codes can be entered when the access to the verification methods selected during the setup is not available.

The backup codes are stored directly in the user account. Each backup code can be used one time only as an alternative to the verification code in the situations when the mobile device with the authenticator app is not available and there are no other means of getting a verification code. Button Save will create a file with the current set of backup codes. Button Generate will produce a new set of backup codes. It is recommended to print the backup codes and have them stored in the safe place.

Users complete the configuration by pressing the Enable button. This will result in the request to enter a verification code. Type in the verification code displayed in the authenticator app or get the code via email.

Successful input of the verification code will enable the 2-Factor Authentication for the user account. The backup codes are not accepted during the setup verification. The objective of the setup verification is to ensure that the user is able to get the verification codes with the selected methods of delivery.
image5.png
The last step of the 2-Factor Authentication requires the user to enter the verification code displayed in the authenticator app on their device or have it delivered through other methods.

Living With 2-Factor Authentication

The application will still require the user to enter the username and password in the custom or standard Login form.

image21.png
This is the standard login form of an application created with Code On Time. The 2FA verification process will start when the user enters their credentials and presses the Login button.

Successful identification of the user will present the request to input the verification code. The user may opt to enter a one-time use backup code as an alternative to the verification code. Input of the incorrect verification or backup code will count as a failed login attempt. Multiple failed attempts to verify the username and password will result in the locked user account.

image3.png
The prompt to enter a verification code is displayed after the successful confirmation of the username and password. Users must enter the verification code displayed on the screen of their mobile device in the authenticator app or request the verification code through other available methods. The backup codes are accepted in the Backup Code input.

If the device can be trusted then the further requests to input the verification code can be suppressed by selecting the “Trust this device” option. The encrypted cookie with a unique verification code associated with the username and timestamp will be created. The application will verify the code stored in the cookie after the successful sign in to confirm the user identity. No prompt to enter a verification is displayed on the trusted device.

Selection of the verification method may reveal the Get Verification Code button. The verification code is delivered when the button is pressed.

image19.png
Pressing the Get Verification Code button will deliver the verification code in the manner corresponding with the selected verification method. For example, the user will receive an email with the verification code if the email-based verification method is chosen in the 2-Factor Authentication prompt.

The setup screen can be re-entered by choosing the same “2-Factor Authentication” option in the user context menu. Users will be greeted with the verification code input screen before the setup options are presented. Users may change the verification code delivery methods, download the backup codes, or generate a new set of backup codes. Changes will be saved after another successful verification code input.

Disabling 2-Factor Authentication

Users may disable the 2-factor authentication by withdrawing the consent to enter a verification code. The withdrawal of the consent in the setup screen will disable the 2FA for the user account when the Save button is pressed.

image17.png
Users can disable the 2-Factor Authentication through the corresponding option in the user account menu. The 2FA setup form is displayed after a valid verification code is entered in the prompt. The user must withdraw their consent to enter a verification code to confirm identity and press the Save button.

The multi-factor authentication can be permanently disabled in the application by setting the server.2FA.enabled option to false in the ~/app/touch-settings.json configuration file. The 2-Factor Authentication option will not appear in the user context menu when 2FA is disabled.

JSON
1234567{
  "server": {
    "2FA": {
      "enabled": false
    }
  }
}

Prerequisites

Two-factor authentication requires the additional information to be stored in the user account in the application database. If you have enabled the standard membership feature in your Code On Time app, then there is no need to do anything else. The application will store the 2FA setup in the Comment field of the user membership account.

The screenshot below shows the Comment field of the admin user configured for multi-factor authentication. The Yaml-encoded data includes the secret, backup codes, and verification methods associated with the user account.

image16.png
TBD

If the custom membership manager is configured for the Code On Time application, then make sure to map the Comment logical field to the corresponding column in your own Users table.

The application framework provides two methods in the ApplicationServices class to read and write the user authentication data. Developers may override the ReadUserAuthenticationData and WriteUserAuthenticationData methods to store the data elsewhere. The code below shows the default implementation of both methods.

C#
123456789101112131415public partial class ApplicationServices 
{

    protected override string ReadUserAuthenticationData(MembershipUser user)
    {
        return user.Comment;
    }

    protected override void WriteUserAuthenticationData(MembershipUser user, string data)
    {
        user.Comment = data;
        Membership.UpdateUser(user);
    }

}

Verification Code with SMS and Call

Developers may enable three additional methods of verification code delivery in the app. These include sms, call, and dial. Enter the following options in the ~/app/touch-settings.json file of your application to enable these methods:

JSON
12345678910111213{
  "server": {
    "2FA": {
      "verify": {
        "app": true,
        "email": true,
        "sms": true,
        "call": true,
        "dial": "1-877-467-6340"
      }
    }
  }
}

Re-enter the 2FA setup and enable the verification code delivery via text message and call. Save the setup.

image8.png
Additional verification methods will appear when the application is configured to deliver the verification codes via text message, voice call, or direct dial.

Verification methods app and email are enabled by default and available on the 2FA setup screen. Delivery via email will require specifying the SMTP server parameters in Settings | Features | Smtp Configuration section of the project configuration.

There is no built-in support for sms or voice call delivery of the verification code in the framework. Developers may sign up for the text and voice delivery services from their favorite messaging provider and override two methods in the ApplicationServices partial class.

Method OtpVerificationData must provide the means of verification code delivery for the given username parameter. The implementation below uses the sample static values.

Method OtpAuthenticationSendVerificationCode implements the physical delivery of the verification code. The implementation must send the contents of the message parameter to the contact using the code specific to the messaging provider.

C#
12345678910111213141516171819202122232425262728293031323334353637383940414243using System;
using Newtonsoft.Json.Linq;

namespace MyCompany.Services
{

    public partial class ApplicationServices
    {
        protected override void OtpVerificationData(string username, JObject verify)
        {
            base.OtpVerificationData(username, verify);
            // developer can override this method and supply alternative sms numbrersverify
            verify["sms"] = "123-456-7890";
            verify["call"] = new JArray("123-456-7890", "877-467-6340");
            if (verify["email"] != null)
                verify["email"] = new JArray(
                    "customerservice@codeontime.com",
                    Convert.ToString(verify["email"]));
        }

        protected override string OtpAuthenticationSendVerificationCode(
            string code, string type, string contact,
            string message, string confirmation)
        {
            if (type == "sms")
            {
                // send the SMS "message" to the "contact"
                // TODO: implement the sms delivery here
                return confirmation;
            }
            else if (type == "call")
            {
                // send the voice "message" to the "contact"
                // TODO: implement the voice call delivery here
                return confirmation;
            }
            else
                return base.OtpAuthenticationSendVerificationCode(
                    code, type, contact, message, confirmation);
        }
    }

}

The screenshot below shows the code in Debug mode when the sms verification method is selected by the user.

image1.png
The verification code delivery implementation is shown while being debugged in Visual Studio. The code simply returns the confirmation that was “delivered” via the selected verification method. Developers must implement their own custom code to deliver the message value via text message or voice call.

Users will initiate the delivery by selecting the corresponding method and pressing the Get Verification Code button. The delivery confirmation message will be displayed at the bottom of the screen. The framework obfuscates the email addresses and phone numbers available in the list of methods.

image10.png
The confirmation of the verification code delivery is displayed at the bottom of the screen when the Get Verification Code button is pressed.

The dial verification method is entered in the server.2FA.verify.dial option in ~/app/touch-settings.json file. It will provide the user with the phone number to call. Use this delivery method if the live operator will be available to the application users to assist with their identity verification. The operator may enter the one-time use backup code directly into the user account in the Membership Manager or in a custom form. This backup code may be a word or a number that the operator will communicate to the user after their identity is confirmed. The single-use backup code is removed from the user account after the successful verification.

Trust No One

Developers may force the users to always enter the verification code when signing into the app.

The server.2FA.trustThisDevice parameter must be set to 0 in ~/app/touch-settings.json to hide the “Trust this device” option on the verification code input screen.

The default value of the parameter is 180. It specifies the number of days during which the user will be able to avoid entering the verification code when signing into the application after the initial verification with the “Trust this device” option.

If the user has lost access to the “trusted” device then the 2-factor authentication must be disabled and enabled one more time on the user account to invalidate any previous trusts.

Verification Code Length and Period

The default length of the verification code is set to 6 digits that are changing every 30 seconds. Application framework will compare the provided verification code with the codes produced in the 180 second window.

The length of the verification code, the period of change, and the testing window can be changed like this in the ~/app/touch-settings.json configuration file:

JSON
1234567891011121314151617181920212223{
  "server": {
    "2FA": {
      "code": {
        "length": 4,
        "period": 60,
        "window": 600
      },
      "setup": {
        "authentication": [
          {
            "value": "https://play.google.com/store/apps/details?id=com.salesforce.authenticator",
            "text": "Salesforce Authenticator (Android)"
          },
          {
            "value": "https://apps.apple.com/us/app/salesforce-authenticator/id782057975",
            "text": "Salesforce Authenticator (iOS)"
          }
        ]
      }
    }
  }
}

The longer testing window can be specified if the delivery of the verification codes is slower than 3 minutes.

The server.2FA.code.window parameter is provided exclusively for the application. It will generate multiple verification codes in the specified time window to find the match to the verification code provided by the user.

Do not change the length and period if you expect the end users to work with the authenticator apps from Google or Microsoft. These apps will ignore the parameters and generate the 6 digit code every 30 seconds.

Salesforce Authenticator will respect the length and period parameters. It will correctly generate the 4-digit verification code every 60 seconds as instructed by the app.

image12.png
The Salesforce Authenticator app will respect the length and period parameters of the verification code configured in the app. The screenshot shows the 4 digit verification code displayed to the user on the mobile device. Other vendors may not have support for these parameters. Make sure to test the expected authenticators to ensure their ability to display the correct verification code that matches the application configuration.

Developers can specify their own set of the authenticator apps to be available on the setup screen. Option server.2FA.setup.authenticators is an array of name/url pairs in ~/app/touch-settings.json configuration file. This custom set is presented to the user asking for help with the installation of the authenticator app. Users are prompted to scan the QR code with the device camera, which will present user with the link leading to the app store directly on the device.

image4.png
Developers can configure their own Authenticator App suggestions to be presented to the users. The screenshot shows two recommendations to install the Salesforce Authenticator for Android or iOS.

Backup Codes

By default the 2FA setup will produce ten 8-digit backup codes. Developers may opt to configure their own set of backup codes.

JSON
12345678910{
  "server": {
    "2FA": {
      "backupCodes": {
        "length": 3,
        "count": 5
      }
    }
  }
}

This configuration will produce a set of five 3-digit backup codes.

image15.png
A custom set of 3-digit backup codes is presented in the form. Users can generate a new set of codes and have the current saved. Users must always Save the 2FA setup form to ensure that the re-generated backup codes are persisted in their user account.

Users must print or save the backup codes and use them if the access to the verification methods selected during the setup is lost.

Auto-Setup

By default the 2-Factor Authentication requires users to opt in. Developers have an option to automatically generate the 2FA setup for the user accounts at the moment when the user is singing in.

For example, the following configuration in ~/app/touch-settings.json will automatically create the 2FA setup with the email-based delivery of verification codes.

JSON
123456789101112131415{
  "server": {
    "2FA": {
      "setup": {
        "mode": "auto",
        "methods": {
          "app": false,
          "email": true,
          "sms": false,
          "call": false
        }
      }
    }
  }
}

Users will enter the username and password and press login. The framework will create the 2FA setup if it does not exist. Users will be immediately presented with the request to enter the verification code. The only option to get the verification code is the email.

image20.png
The screenshot shows the 2-Factor Authentication prompt with the email-based verification method that will be presented in the application to all users when automatic 2FA setup is enabled.

Make sure to set up the SMTP Configuration in the Settings | Features of the application. Otherwise users will not be able to access the application.

Applications may support the other methods of verification that can be configured in the server.2FA.verify section of ~/app/touch-settings.json as explained above. Users will need to enter the setup mode through the user context menu to change their verification preferences.

If a user withdraws the consent to enter the verification code, then the application will perform the automatic setup during the next sign in to keep the user accounts protected.

Login Without Password

Automatic setup makes it possible to disable the requirement to enter the password during the setup. Set the server.2FA.disableLoginPassword key to true and server.2FA.setup.mode to auto in touch-settings.json. Optionally specify the automatic setup methods. The default setup method of verification code delivery is email.

JSON
1234567891011{
  "server": {
    "2FA": {
      "disableLoginPassword": true,
      "setup": {
        "mode": "auto"
      },
      "trustThisDevice": 0
    }
  }
}

The built-in login form will not ask the user to enter the password.

image2.png
The Password input field is hidden in the standard Login form if the application is configured for login without password.

The framework will locate the user account by name. If the user is found, then the automatic 2FA setup is performed when needed. The user will be asked to enter a verification code to sign in. Each user account will have a unique random-generated secret. This secret determines the time-sensitive verification code that needs to be entered to verify the login.

The initial verification is done via email. Users may opt to enable the authenticator app verification in the 2-Factor Authentication setup. We also recommend configuring the server.2FA.trustThisDevice option to 0 to ensure that the verification code is always requested.

The login process without password will require the user to enter their name and the time-based verification code displayed in the authenticator app on their mobile device.