How can we prompt for MFA enrolment in a rule or post authentication?

Hi there. We have a use case where we need to enable MFA only for a set of users. We are not giving any option on UI for a user to enroll for MFA. Rather, we want to do this automatically in a rule where we decide if a particular user belongs to the set of users (who has MFA enabled). So our approach is like:

  1. Create a rule.
  2. Inside the rule, fetch the user metadata having a key like useMFA.
  3. if useMFA is true, prompt user for MFA enrollment else
  4. return the user profile.

The main issue is here we don’t know how to prompt the user for enrollment in a rule.
Any suggestions would be helpful.

Hi,

You can redirect flow to any of your desire link after user has been authenticated successfully. Please follow the below link:

Please provide feedback if it help.

Thanks for your response. I will check this out and let you know.

2 Likes

Perfect! We’re here for you!

1 Like

Hi, I have the exact same use case as @mohd.ilyas, but I am unable to figure out what to do in the rule once the check have been made and I know that the user wants to use MFA.

I use non-custom login/mfaLogin screens.

What I’ve done so far is to set context.multifactor to an object with {provider: 'any', allowRememberBrowser: false}.

This triggers MFA login, but it appears to skip enrollment. Since I’ve set up SMS Factor, this means that I am asked to put in my phone number for Auth0 to send a code, and when I click the submit button it says it is unable to due to another enrollment being in progress.

When I look in the admin dashboard for my user, I can see that I am enrolled to email factor, and that there’s an uncompleted enrollment for Recovery Code.

I assume that I need to complete the recovery code enrollment before I can proceed, but the MFA Login screen doesn’t ask me to do this, nor does it present any buttons that allow me to do it.

My assumption is that I configured the rule wrong, but I’m not sure what is the correct way. Did anyone find this out?

Hi @benjaminhubert As per the code you have written for the rule, you should be able to see the MFA enrolment screen and for the first time login, it should also show the recovery code screen where you can copy the code and move on.

In case you left the MFA screen before landing on the recovery code screen, it should again prompt you for the same when you login next time.

I just tried the same approach with a freshly created tenant and I was able to see the recovery code after the OTP step.

If you can show me the code you have written in your rule, I will be able to help you in a better way.

thanks

Thanks for helping, here’s the rule we use, to enable/disable MFA as well as expose a boolean denoting whether the user has MFA enabled:

function handleMultifactorAuthentication(user, context, callback) {
  // to enable/disable add set_mfa: true|false to the login redirect options
  const setMfaQuery = context.request.query && context.request.query.set_mfa;

  const boolLookup = {
      "true": true,
      "false": false
  };

  const setMfa = boolLookup[setMfaQuery];

  // true if MFA should be used
  const mfa =
    setMfa !== undefined
      ? setMfa
      : (user.user_metadata && user.user_metadata.mfa) || false;
      
  // true if user already used MFA to authenticated in this session
  const completedMfa = !!context.authentication.methods.find(
    (method) => method.name === "mfa"
  );

  // if we should use mfa and we haven't already, enable it
  if (mfa && !completedMfa) {
    context.multifactor = {
      provider: "any",
      // optional, defaults to true. Set to false to force authentication every time.
      // See https://auth0.com/docs/multifactor-authentication/custom#change-the-frequency-of-authentication-requests for details
      allowRememberBrowser: false,
    };
  }

  // put whether the user has mfa enabled in the id token so we can display it in frontends
  context.idToken["http://mfa"] = mfa;

  // if the user is changing their MFA value, save it
  if (setMfa !== undefined) {
    // merge in the new MFA value
    user.user_metadata = user.user_metadata || {};
    user.user_metadata.mfa = setMfa;

    // save the settings and proceed in the flow
    auth0.users
      .updateUserMetadata(user.user_id, user.user_metadata)
      .then(function () {
        callback(null, user, context);
      })
      .catch(function (err) {
        callback(err);
      });
  } else {
    callback(null, user, context);
  }
}

@benjaminhubert Can you try with a new rule Multifactor Authentication rule that it already created in Auth0? Also, create a new user.

thanks

For reference, my SMS Factor is setup using Twilio as follows.

@ilyas-shah Yes I will try right away!

@ilyas-shah I disabled my custom MFA rule and added the base Multifactor Authentication. I tried the signup flow, but I am immediately prompted to insert my phone number, even before I am able to to create a new user.

If I reset my old user’s MFA and try to put in my phone number I get

We couldn’t send the SMS. Please try again later.

Okay, it appears that the SMS issue was due to an invalid alphanumeric sender name, as per Twilio’s requirements:

Formatting Requirements

Alphanumeric Sender IDs can contain up to 11 characters from the following categories:

  • Upper-case letters A - Z
  • Lower-case letters a - z
  • Numbers 0 - 9
  • Spaces

Sender IDs must contain at least one letter. Special characters and punctuation are not allowed.

Note: In India , Alphanumeric Sender IDs must contain exactly 6 characters.

With that solved, it works for the non-custom login/mfaLogin screens.
Thanks for the help!!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.