Multi factor authentication enrollment without prompting user for phone number?

I want to implement multi factor authentication in my application. I send an enrollment email to the user, and when they click on the enrollment link in the email, they are taken to an Auth0 universal login-esque page to enroll their phone number. However, as part of the SLAs with our company clients, all of their user’s email and phone numbers provided to us are assumed to be verified. Thus, we do not want the users to enter their own phone numbers when enrolling for multi factor authentication because of the possibility that they might enter a number different from the one given to us by our clients (i.e. the user’s employers).

So, I have two questions in this regard:

  1. Can we enroll users directly using the management API without any interaction from the users themselves? I have tried setting a user’s phone number using the management API but it says that only users with SMS connections (i.e. passwordless login users) can be assigned phone numbers using the management API. Our connection type is database.

  2. Is there any way to disable the option for the user to enter any phone number when enrolling for multi factor authentication, thus allowing us to enter the phone number of the user that was given to us by the user’s employers, in the Auth0 enrollment web page after the user clicks on the enrollment link it the email.

I have looked up the auth0-guardian JS library as well to implement this functionality manually in my front end application, but I am unable to user that library because I am unable to initialize it without a request token or ticket. The documentation is not clear on how to get either of these.

It may be possible to enforce a specific phone number for MFA by using the MFA API to enroll the user with SMS/Voice while having control of the phone number used. You would need to get an access token for the MFA API as part of the user login (Manage Authenticator Factors with Auth0 MFA API) and with that access token call the enroll endpoint (Enroll and Challenge SMS and Voice Authenticators) which from the docs would accept the phone number.

We are using the auth0 javascript web SDK. Is it possible to perform this using the auth0.WebAuth object in that library? Or do we need to implement this in the backend?

Going by the reference documentation if you use Auth0.js SDK to start a login flow through universal login you would only need to ensure that you include the MFA API audience when doing the request. The likely consideration is that if you’re already requesting an audience (for example, for your own API) this would imply you would need to do a separate request as you can only request a single audience per request.

However, although it may require an additional request it’s likely the user would not have to authenticate again as the second one would be satisfied by the existing session and could likely be completed without interaction.

1 Like

I’m sorry, but I need a little more clarity on your response.

Yes, we are using the Auth0.js library and the login flow is authenticated at the /co/authenticate endpoint. This results in a redirect through Auth0 to an resource on our server with a parseHash string containing the access_token, id_token and other information.

If I enable MFA on my application, this login redirects to the MFA screen (enrollment or authentication depending on the user’s MFA enrollment status) and back to the web page I mentioned earlier with the access_token, id_token, etc. as usual.

What I require, is that this redirect to the Auth0 MFA screen be disabled somehow so that I can receive the MFA token that I can use in a custom MFA enrollment/authentication flow myself.

I think the issue here is that the Auth0.js library is making a call to /co/authenticate which is causing the redirects as mentioned. That is because if I were to login to /oauth/token using curl:

curl \
--request POST   \
--url 'https://domain.auth0.com/oauth/token'   \
--header 'content-type: application/x-www-form-urlencoded'   \
--data grant_type=http://auth0.com/oauth/grant-type/password-realm   \
--data username=user@email.com   \
--data password=SomePassword12345   \
--data 'client_id=REDACTED'   \
--data client_secret=REDACTED   \
--data audience=https://API_AUDIENCE   \
--data 'scope=openid profile read:sample'   \
--data 'realm=REDACTED'

and if MFA is enabled, I receive the following response:

{"error":"mfa_required","error_description":"Multifactor authentication required","mfa_token":"REDACTED"}

So, I want this same response, but from using some function in the Auth0.js library.

The caveat here however, is that I have to pass my client secret as one of the parameters, which we don’t want to store in the front end. So, if I could get a response like this instead of the redirect to Auth0’s MFA page from the Auth0.js library itself, that would be a start. Someway not involving storing the client secret in the frontend would be best as well.

Currently the login is performed in this way:

    webAuth.login(
			{
				realm: AUTH_CONFIG.connection,
				username: email,
				password: password,
				audience: 'https://domain.com',
				responseType: 'token id_token',
				redirectUri: callbackUrl
			},
			(err1, authResult) => {
				showLoader(false);
				if (err1) {
					setErr(err1.error_description);
					setDisableForm(false);
				}
			}
		);

This authenticates from /co/authenticate, so, I need to know can we use this same flow somehow to authenticate with /oauth/token instead?

The response you mentioned from /oauth/token is specific to that particular endpoint, so you won’t get a similar one when using either universal login (redirecting to /authorize directly) or embedded login through cross-origin authentication (what you use now).

You can use audience with cross-origin authentication, however, you will need to ensure that MFA is only triggered if a user is already enrolled in order to prevent the chicken and egg problem you’re right now where doing the login triggers MFA enrollment through universal login page.

In order to achieve the above it should be possible to use a rule to control when MFA is triggered instead of always triggering MFA. The rule could use a flag in user metadata to know for which users to trigger it; this should allow you to use cross origin authentication with the MFA audience for users who don’t yet have enrolled so that you then try to enrol them with a specific phone number.

As I originally mentioned, I’m afraid I haven’t recently gone through actually performing this flow so there may be details that I miss, however, to my knowledge all of the above should be doable. Also have in mind, that if you don’t want to do stuff from a backend and instead make requests from client-side code it will be technically possible for a more savvy user to intercept those requests and still enrol whatever phone number they want instead of the one you were trying to select for them.

Hi,

I really appreciate your replies, by the way, I have been banging my head against the keyboard for the last two weeks trying to meet the requirements of management regarding this. Though I am not really close to solving this, I appreciate your help in this regard. Just thought I should tell you this.

As for the matter at hand, I have been re-designing our application to use the /oauth/token calls from the backend for all authentication. Thus, the frontend would pass the user’s credentials to the backend, bypassing the Auth0 JS library.

In the backend, we check whether the user is enrolled or not. If the user is enrolled, we use the sms authenticator to challenge the user otherwise we enroll the user. Ultimately, the backend returns the access_token to the frontend, which the frontend uses to make API calls.

This is as described in this page: Enroll and Challenge SMS and Voice Authenticators

I feel this is a bit too complicated, but I guess workarounds have to be made. I would have really appreciated if Auth0 had provisions for such use cases by default.

Hi João:
I am Sargent_D’s manager, stepping into this conversation to help clarify the requirement. We seed our user database with trusted emails and phone numbers. We would like to use both as roots of trust when enrolling a user. Since we don’t trust the user unless they can confirm ownership of both the email and the cell number, we need to pre-populate their second factor at the outset.

Is this workflow possible through Auth0 or not?

Thanks.
-Raj

Hi João:
Can I get a response?

As I mentioned before it’s technically possible for you to have control over the enrolment process and use a phone number that you already have, however, this will be possible under certain conditions and requires additional logic on your own system. It could be argued that this could be simpler and have additional built-in support for this use case, but to my knowledge what’s possible now is what I already mentioned before. Beyond that I recommend you to use Auth0: Secure access for everyone. But not just anyone. to relay any comments about the current experience and provide suggestions about how it could be improved. Any feedback submitted through that channel will be reviewed by the product team.

2 Likes

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