Add MFA based on user device


# Add MFA based on user device

You can apply the New-Device-Based conditional authentication template to your application to enable a more secure login flow for users who log in from a previously unused device.

When the user signs in from a previously unused device, this template enables two-factor authentication and/or sends an email notification when the user passes the first authentication step. A cookie is used to identify whether the device has been used before. When the cookie expires (this expiry time is specified in the template), the same browser or device is considered a new device.

# Scenario

Consider a scenario where users who log in to an application from a new device or browser should be prompted with TOTP as a second authentication step. The two authentication steps are as follows:

  1. Username and password
  2. TOTP

An email should also be sent to the user with details of the login attempt.

# Prerequisites

You need to register an application with Asgardeo. You can register your own application or use one of the sample applications provided.

# Configure the login flow

To enable conditional authentication:

  1. On the Asgardeo Console, click Applications.

  2. Select the relevant application and go to it's Login Flow tab.

  3. Add new device-based adaptive MFA using your preferred editor:

    Using the Classic Editor

    To add new device-based adaptive MFA using the classic editor:

    1. Click Start with default configuration to define the login flow starting with the username and password login.

    2. Turn on Conditional Authentication by switching the toggle on.

    3. Select the Request > Device-Based template.

    Using the Visual Editor

    To add New-Device-based adaptive MFA using the visual editor:

    1. Switch to the Visual Editor tab, and expand Predefined Flows > Conditional Login Flows > Adaptive MFA.

    2. Click + ADD next to New-Device-Based to add the IP-based adaptive MFA script.

    3. Click Confirm to replace any existing script with the selected predefined script.

    Important

    As a security measure, Asgardeo does not allow the usage of two consecutive periods (..) in authentication scripts.

  4. Verify that the login flow is now updated with the following two authentication steps:

    • Step 1: Username and Password
    • Step 2: TOTP
  5. Update the following parameters in the script.

    Parameter Description
    sendNotification

    Specifies whether email notifications should be sent to users.

    For this scenario, set this parameter to true.
    cookieName A user-defined cookie name to be used for device identification.
    deviceRememberPeriod

    The length of time in seconds for which this device should be remembered as a trusted device. Once this time period passes, login attempts are considered as new device logins.

    For example, you can specify two years as follows: 60 * 60 * 24 * 365 * 2

  6. Click Update to confirm.

# How it works

Shown below is the script of the device-based conditional authentication template.

// This script will step up authentication and send email notification in case of
// a user being logging in from a new device (identified by a cookie).

// Amount of time in seconds to remember a device. Set to 2 years below.
var deviceRememberPeriod = 60 * 60 * 24 * 365 * 2;

// Cookie name to be set
var cookieName = 'deviceAuth';

// Whether to send a notification on new device login
var sendNotification = true;

// Whether to step up authentication for new device login
var stepUpAuthentication = true;

// Email template to be used for new device login notification
var emailTemplate = 'UnseenDeviceLogin';


var onLoginRequest = function(context) {
    executeStep(1, {
        onSuccess: function (context) {
            subject = context.currentKnownSubject;
            if (!validateCookie(context, subject)) {
                Log.debug('New device login with ' + subject.uniqueId);

                if (sendNotification === true) {
                    var templatePlaceholders = {
                        'username': subject.uniqueId,
                        'login-time': new Date().toUTCString()
                    };
                    var isSent = sendEmail(subject, emailTemplate, templatePlaceholders);
                    if (isSent) {
                         Log.debug('New device login notification sent to ' + subject.uniqueId);
                    } else {
                         Log.debug('New device login notification sending failed to ' + subject.uniqueId);
                    }
                }

                if (stepUpAuthentication === true) {
                    Log.debug('Stepping up authentication due to a new device login with ' + subject.uniqueId);
                    executeStep(2, {
                        onSuccess: function (context) {
                            setCookie(context.response, cookieName, subject.uniqueId, {
                                'sign': true,
                                'max-age': deviceRememberPeriod,
                                'sameSite': 'LAX'
                            });
                        }
                    });
                }
            }
        }
    });
};

//Validate if the user has a valid cookie with the value as subject's username
var validateCookie = function(context, subject) {
    var cookieVal = getCookieValue(context.request, cookieName, {'validateSignature': true});
    return subject.uniqueId === cookieVal;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

Let's look at how this script works.

  1. The validateCookie function verifies whether the user has a valid cookie for the logged-in user. This function calls the getCookieValue(request, name, properties function. The cookie name is configured with the cookieName parameter.

  2. When step 1 of the authentication flow is complete, the onLoginRequest function validates the deviceAuth cookie.

  3. If there is no valid cookie found, the function checks whether the sendNotification and stepUpAuthentication parameters are enabled.

  4. If the sendNotification property is enabled, the sendEmail(user, templateId, placeholderParameters) function is called to send the notification email with the login timestamp. The email template is set as UnseenDeviceLogin in the emailTemplate variable.

  5. If the stepUpAuthentication parameter is enabled, step 2 of the authentication flow is executed.

  6. On the successful execution of step 2 of the authentication flow, the setCookie(response, name, value, properties) function is called to set a deviceAuth cookie.

Find out more about the scripting language in the Conditional Authentication API Reference.

# Try it out

Follow the steps given below.

  1. Access the application URL from a new device/browser.

  2. Try to log in to the application. TOTP authentication is prompted and the configured email of the user receives the email notification. new-device-email-notification-sample

  3. Log out of the application.

  4. Log in with the same user from the same device/browser. You will successfully log in to the application with only the basic authentication.