Mobile Biometrics Authentication

Authenticates the user with mobile biometrics (e.g., fingerprint) using the client SDK

About client-facing steps

A journey is a sequence of steps that are executed when it's invoked by a client application (known as the "client"). Some steps require involvement from the client, such as to collect user input. Other steps, like validating a token, are executed in the backend by the Mosaic journey engine alone.

When invoked, the journey begins executing the steps while the client waits for further instructions. When a journey reaches a client-facing step, the journey asks the client for the required input and then waits for the client to respond. The client presents their own UI if user interaction is required, and returns input to the journey. The journey then proceeds in a similar manner until it's completed.

Description

This client-facing step is used to authenticate the user using mobile biometric credentials (e.g., Face ID or fingerprint). The biometric credentials must be registered using the Register Mobile Biometrics step.

Once triggered, this step instructs the client to authenticate biometric credentials on the device. The client does this using the Authentication SDK calls, which will prompt the user for biometrics (e.g., fingerprint). If successful, the SDK returns the authentication result. The client submits this result to the journey using the IDO SDK call to complete the registration.

If successful, the journey sets the user context to the authenticated user and continues to the next step. User tokens generated upon authentication can be accessed in subsequent steps using @policy.userTokens(). If it fails or is cancelled, the journey is either aborted or proceeds to the dedicated cancel or failure branches (if configured).

To support mobile biometric authentication, you'll need to:

  • Implement biometric registration, as described here
  • Implement the Authentication SDK calls required for authentication, as described here
  • Implement the IDO SDK call that submits the authentication result (see Android IDO SDK reference or iOS IDO SDK reference )
  • Configure the Mobile Biometrics Authentication journey step
Note

For requirements and instructions on how to set up Authentication SDK on Android and iOS, see the Android quickstart and the iOS quickstart (skip Step 3 and 4). For Android, this requires the Authentication SDK with compileSdk 34 (or greater) and minSdk 23.

Configuration

Field Description
Username source Specifies the source of the user identifier. The username can either be provided by the client upon authentication (default) or provided by the journey (after resolving the configured source expression).
User Identifier User identifier, specified as an expression. Must be configured only if the journey is configured as the username source.
Error Output Variable Name of the variable that stores any errors returned by action
Failure Behavior Determines the behavior in case of failure, which either aborts the journey or proceeds to a failure branch of the control flow (default).
Custom Branches Additional journey branches supported for this step. The client can select a branch by returning the branch ID. For each branch, you can define a schema for the information that the client is expected to return (used by the code generator and for autocompleting journey expressions) and a display name to label it in the editor.
Branch Output Variable Name of the variable used to store the data returned by the client, which can be used in subsequent journey steps.
Cancel Behavior Determines the behavior of client cancellation, which either aborts the journey (default) or proceeds to a cancel branch of the control flow

Example

Consider a journey that only authenticates the user using mobile biometrics. Our example assumes that the client stores the user identifier and will provide it to the journey upon authentication:

When executed, this step sends a callback to the client with the IDO service response object. It will have the journeyStepId set to authenticateNativeBiometrics and the data will include a challenge generated implicitly by the IDO service. The client authenticates the user using their biometric credentials, and signs the challenge. The client then returns the authentication result to the journey to complete the step.

KotlinSwift
Copy
Copied
// User identifier stored by the client
val userIdentifier = getUserId()
// Authentication challenge provided by the journey
val challenge = (idoResponse.data as JSONObject).optString("biometrics_challenge")
activity?.let {
  // Authenticates the user with their biometric credentials using the Authentication SDK
    TSAuthentication.authenticateNativeBiometrics(it as AppCompatActivity, userIdentifier, challenge, BiometricPromptTexts("Authentication", "Place your finger on the sensor", "Abort"),
        object: TSAuthCallback<TSBiometricsAuthResult, TSBiometricsAuthError> {
            override fun error(error: TSBiometricsAuthError) {
                //handle error
            }

            override fun success(result: TSBiometricsAuthResult) {
                Log.d(TAG, "Biometrics authentication success")
                // Submits the authentication result to the journey using the IDO SDK
                submitResponse(TSIdoClientResponseOptionType.ClientInput.type, BiometricsAuthenticationResult(result.keyId(), userIdentifier, result.signature()))
            }
        })
}

data class BiometricsAuthenticationResult(val publicKeyId: String, val userIdentifier: String, val signedChallenge: String)
Copy
Copied
// Authentication challenge provided by the journey
guard let challenge = serverResponse?.data["biometrics_challenge"] as? String else {
    return
}

// Authenticates the user with their biometric credentials using the Authentication SDK
TSAuthentication.shared.authenticateNativeBiometrics(username: "[USER_ID]", challenge: challenge) { result in
    switch result {
    case .success(let response):
        let data: [String: Any] = [
            "publicKeyId": response.publicKeyId,
            "signedChallenge": response.signature,
            "userIdentifier": "[USER_ID]"
        ]

        // Submits the authentication result to the journey using the IDO SDK
        TSIdo.submitClientResponse(clientResponseOptionId: .clientInput, data: data)
    case .failure(let error):
        debugPrint("[DEBUG] Error: \(error)")
        TSIdo.submitClientResponse(clientResponseOptionId: .fail)
    }
}