Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This tutorial demonstrates how to implement Email strong authentication method registration into your iOS/macOS app using native authentication. At least one strong authentication is mandatory for MFA-enabled users. We support email and SMS as strong authentication method.
In this tutorial, you learn how to:
- Register a strong authentication method for a MFA-enabled user.
Prerequisites
Complete the steps in Tutorial: Add sign-in and sign-out in iOS/macOS app by using native authentication.
To enforce multifactor authentication (MFA) for your customers, use the steps in Add multifactor authentication (MFA) to an app to add Email OTP MFA to your sign-in flow. We support email and SMS one-time passcode MFA. Therefore, email as second factor is only available when the authentication method is email with password.
If you'd like to explore our strong authentication method registration implementation, take a look at our Code sample before getting started.
Configure strong authentication method registration capabilities
Set the registrationRequired capability during client initialization to support strong authentication method registration.
let config = try MSALNativeAuthPublicClientApplicationConfig(
clientId: Configuration.clientId,
tenantSubdomain: Configuration.tenantSubdomain,
challengeTypes: [.OOB, .password]
)
config.capabilities = [.registrationRequired]
nativeAuth = try MSALNativeAuthPublicClientApplication(nativeAuthConfiguration: config)
Register email one-time passcode as strong authentication method
To register an email one-time passcode for an MFA-enabled user, you can either use the default email address provided during account creation or specify an alternative email address as the strong authentication method. This process is triggered only the first time the MFA is required, and the user doesn't have a strong authentication method registered. Afterward, you need to send an email containing a one-time passcode for the user to verify their email address. Once the user enters a valid one-time passcode, the SDK completes the sign-in process.
To register a strong authentication method (email one-time passcode) for MFA-enabled user, you need to:
Create a user interface (UI) to:
- Advise the user that strong authentication method registration is required to sign in (optional).
- Collect an email address to be registered as strong authentication method (optional). If the user doesn't provide an email address, the default email address provided during account creation will be used.
- Collect an email one-time passcode from the user to fulfill two-factor authentication.
- Resend one-time passcode (recommended).
Implement the
onSignInStrongAuthMethodRegistrationmethod as part of theSignInStartDelegateprotocol:extension ViewController: SignInStartDelegate { // previous code omitted func onSignInStrongAuthMethodRegistration(authMethods: [MSALAuthMethod], newState: RegisterStrongAuthState) { // inform the user that registration is required let alert = UIAlertController( title: "Missing strong authentication method", message: "Registration of strong authentication method is required. Do you want to proceed with registration?", preferredStyle: .alert ) // You can select the first authMethod which has a challengeChannel of type email // Or use "actionResult.authMethods" to let the user pick the authentication method to use. var authMethod = actionResult.authMethods.first { $0.channelTargetType.isEmailType } alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in if verificationContact.isEmpty { verificationContact = "user@contoso.com" // You can use the email address provided during account creation or specify an alternative email address. } let parameter = MSALNativeAuthChallengeAuthMethodParameters(authMethod: authMethod, verificationContact: verificationContact) newState.challengeAuthMethod(parameters: parameter, delegate: self) })) alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { _ in self.resultTextView.text = "Strong authentication method registration is required" })) present(alert, animated: true) }The
signIn(username:password:delegate)results in a call to delegate methods. TheonSignInStrongAuthMethodRegistration(authMethods:newState)method handles the scenario where registration of a strong authentication method is required. You can present an alert to the user, asking if they want to proceed with registration. If the user chooses OK you request the MFA challenge by callingnewState.challengeAuthMethod(parameters:delegate). ThenewState.challengeAuthMethod(parameters:delegate)method sends the strong authentication method to the server for registration.If you prefer not to inform the user about the necessity for registration, you can bypass the user interaction by directly invoking
newState.challengeAuthMethod(parameters:delegate). ThechallengeAuthMethodaccepts a parameter and a delegate instance, you must implement the required methods in theRegisterStrongAuthChallengeDelegateprotocol.Implement the
RegisterStrongAuthChallengeDelegateprotocol:extension ViewController: RegisterStrongAuthChallengeDelegate { func onRegisterStrongAuthChallengeError( error: RegisterStrongAuthChallengeError, newState: RegisterStrongAuthState? ) { resultTextView.text = "Error registering strong authentication method: \(error.errorDescription ?? "no description")" } func onRegisterStrongAuthVerificationRequired( result: MSALNativeAuthRegisterStrongAuthVerificationRequiredResult ) { let newState = result.newState if verificationContact.isEmpty { verificationContact = "user@contoso.com" // You can use the email address provided during account creation or specify an alternative email address. } let parameter = MSALNativeAuthChallengeAuthMethodParameters(authMethod: authMethod) newState.challengeAuthMethod(parameters: parameter, delegate: self) } }In the most common scenario, you receive a call to
onRegisterStrongAuthVerificationRequired(result)to indicate that the SDK expects the app to submit the email one-time passcode sent to email address. Once the submission is complete, you can call thechallengeAuthMethodmethod like thisnewState.challengeAuthMethod(parameters:delegate). ThechallengeAuthMethodaccepts a delegate parameter and you must implement the required methods in theRegisterStrongAuthSubmitChallengeDelegateprotocol.Implement the
RegisterStrongAuthSubmitChallengeDelegateprotocol:extension ViewController: RegisterStrongAuthSubmitChallengeDelegate { func onRegisterStrongAuthSubmitChallengeError( error: RegisterStrongAuthSubmitChallengeError, newState: RegisterStrongAuthVerificationRequiredState? ) { resultTextView.text = "Error submitting challenge: \(error.errorDescription ?? "no description")" newState.submitChallenge(challenge: "newCode", delegate: self) } func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { print("Signed in as: \(result.account.username ?? "unknown user")") } }The
RegisterStrongAuthSubmitChallengeDelegateprotocol enables you to handle verification code submission. It provides methods to manage errors, such as invalid codes throughonRegisterStrongAuthSubmitChallengeError, allowing resubmission. When the verification is successful, theonSignInCompletedmethod is called and the sign-in process is finalized.