Challenge the User for MFA before a redirection in Actions

Overview

This article describes how to challenge the user for Multi-factor Authentication (MFA) during the authentication flow before a redirection is issued from an Action or a form is rendered.

Applies To

  • Login flows with an MFA challenge and a redirection
  • Form rendering
  • Actions

Cause

When triggering MFA using the global tenant policy or using api.multifactor.enable('any'), if a redirection or form rendering is present on the Actions pipeline, the MFA challenge will always be the last step, even if the redirection is called after the MFA challenge statement.

Solution

The workaround is to use the methods explained in Sequenced and contextual flows.

When using these methods:

  • challengeWith
  • challengeWithAny
  • enrollWith
  • enrollWithAny

The flow is paused, which allows the user to get the MFA challenge before being redirected, assuming there is a redirection statement in a subsequent Action.

Example code:

Action 1:

exports.onExecutePostLogin = async (event, api) => {
    if (event.transaction?.protocol === 'oauth2-refresh-token') {
        return;
    }

    const enrolledFactors = event.user.enrolledFactors;

    if (enrolledFactors && enrolledFactors.length > 0) {
        let factors = [];
        enrolledFactors.forEach((f) => {
            factors.push({ type: f.type });
        });
        console.log("Enrolled factors: ", factors);
        api.authentication.challengeWithAny(factors);
    } else {
        console.log("No factors enrolled, proceeding with Enrollment");
        api.authentication.enrollWithAny([{ type: 'phone' }, { type: 'webauthn-platform' }]);
    }
};

Action 2:

exports.onExecutePostLogin = async (event, api) => {
  api.redirect.sendUserTo("https://something.com");
};