How to Enroll a User in Both Google Authenticator and SMS with MFA API

Problem Statement:

How to Enroll a user in multiple authentication factors with MFA API

Solution:

Assume that we have created a new user who is not enrolled in any MFA authenticator, and we want to enroll the user with SMS and then Google OTP Authenticator.

Prerequisites:

1.enable the MFA under the Application Advanced Settings → Grant Type

2.Enable both Google Authenticator and SMS under Security → Multi-factor Authentication.




Here are the steps to enroll in SMS Authenticator:

1.Request an MFA API access token for the user when they are logging in.

  • In order to generate this token, an audience of https://{YOUR_DOMAIN}/mfa/ with the enroll scope must be passed with the request to /authorize the user.
  • The user will then log in/authenticate, including authentication of their existing primary MFA factor.
  • An access token will be returned with the MFA API identifier in the aud array.
  • This access token will be used as the MFA_API token
Here is an example login request that includes the MFA API audience param and the enroll scope:

GET https://YOUR_DOMAIN/authorize?
response_type=code|token&
client_id=YOUR_CLIENT_ID&
connection=CONNECTION&
redirect_uri=[https://YOUR_APP/callback&](https://your_app/callback&)
audience=https://YOUR_DOMAIN/mfa/
scope=openid%20profile%20email%20enroll&
state=STATE

(NOTE: it is very likely that you would use an Auth0 SDK to make this request, and simply need to manipulate the audience and scopes parameters of the existing request to log the user in.)

2.Pass the access token to enroll the SMS authenticator.

curl --request POST \
  --url '{YOUR_DOMAIN}/mfa/associate' \
  --header 'authorization: Bearer {ACCESS_TOKEN}' \
  --header 'content-type: application/json' \
  --data '{ "authenticator_types": ["oob"], "oob_channels": ["sms"], "phone_number": "+15551234567" }'

This request will return the oob_code like below:

{“authenticator_type”:“oob”,“binding_method”:“prompt”,“oob_channel”:“sms”,“oob_code”:“Fe26.282dcca00….MoJZ1Q3k”}

And on the phone, receive the 6 digits binding_code.

3.Confirm SMS enrollment with the access token and oob_code and binding_code.

curl --request POST \
  --url '{YOUR_DOMAIN}/oauth/token' \
  --header 'authorization: Bearer {ACCESS_TOKEN}' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data 'grant_type=http://auth0.com/oauth/grant-type/mfa-oob' \
  --data 'mfa_token={ACCESS_TOKEN}'\
  --data 'client_id={YOUR_CLIENT_ID}' \
  --data ‘client_secret={YOUR_CLIENT_SECRET}’ \
  --data 'oob_code={OOB_CODE}' \
  --data 'binding_code={6_DIGIT_CODE}'

The request will return the access_token for the SMS enrollment like below.
{“access_token”:“eyJhbGciOiJSUzI….E5X7Q”,“scope”:“enroll read:authenticators remove:authenticators”,“expires_in”:600,“token_type”:“Bearer”}

4.Verify on the user setting on the dashboard that SMS is added

Here are the steps to add Google Oauth Factor to the same user:

1.Request an MFA API access token for the user. (this is the same as the method used in the SMS example. See above).

2.Use the access_token to enroll Google OTP authenticator

curl --request POST \
  --url '{YOUR_DOMAIN}/mfa/associate' \
  --header 'authorization: Bearer ACCESS_TOKEN' \
  --header 'content-type: application/json' \
  --data '{ "authenticator_types": ["otp"] }'

The request will return the secret {SECRET} and barcode_uri.

{“authenticator_type”:“otp”,“secret”:“G5ESY….2B6”,“barcode_uri”:“otpauth://totp/prod-onboarding:lihua.zhang%2Baab%40okta.com?secret=G5ESYORWGZXC6NJUIMRSCORKOI7WW2B6&issuer=prod-onboarding&algorithm=SHA1&digits=6&period=30”}G254DXJW7M

3.Get the OTP code from Google Authenticator App.
Open the Google Authenticator, click on + and select “Enter a setup key”,
Account: {YOUR_EMAIL_ADDRESS}
Key: {SECRET}, which is the secret from the previous step.

4.Confirm OTP enrollment:

curl --request POST \
  --url '{YOUR_DOMAIN}/oauth/token' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=http://auth0.com/oauth/grant-type/mfa-otp \
  --data 'client_id={YOUR_CLIENT_ID}' \
  --data ‘client_secret={YOUR_CLIENT_SECRET}’ \
  --data mfa_token={ACCESS_TOKEN} \
  --data otp={6_DIGIT_OTP_CODE}

{“access_token”:“eyJhb….Dm7-S5icKh0g”,“scope”:“enroll read:authenticators remove:authenticators”,“expires_in”:600,“token_type”:“Bearer”}

5.Confirm that the user is enrolled with both factors in User Settings and by logging in as the user.

Notes:

  1. For the SPA, we should remove client-secret.
  2. For the MFA token, we want to use a user’s access token, with the /mfa API as the audience, and scope set to enroll.
  3. We can use this same token for the header and the mfa_token body parameter
  4. To get a token with the MFA API audience, we need to turn on the MFA grant for that client

References:

https://auth0.com/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-challenge-sms-voice-authenticators#enroll-authenticator

https://auth0.com/docs/secure/multi-factor-authentication/authenticate-using-ropg-flow-with-mfa/enroll-and-challenge-otp-authenticators#enroll-authenticator