Skip to main content

Face authentication

About this documentation

This documentation only describes how to configure the SDK for our face authentication feature. If you want to learn about the feature and the full set of implementation requirements, see the main feature documentation:


Configure the SDK

To use face authentication, you need to:

  1. Configure the local build environment. To do this, add the following dependencies to the Gradle build file:

    Example: Add dependencies to Gradle build file
    /**
    * FaceTec dependencies needed for auth method DEVICE_SERVER_SIDE_FACE
    */
    implementation("com.facetec.android:facetec-sdk:9.6.73@aar")
    implementation("androidx.appcompat:appcompat:1.6.1")
  2. It is possible to preload FaceTec SDK at the start of the Android Activity. To do this:

    Example: Preload the FaceTec SDK
    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Optional - Preload resources related to the FaceTec SDK so that it can be run as soon as possible.
    // Run this as soon as you think you might use the SDK for optimal start up performance.
    FaceTecSDK.preload(this)
    }

How to implement face authentication

Overview

To implement face authentication, you must typically use the following flow:

  1. Invoke the controller start call.
  2. Initialise the FaceScan library with the serverSideFaceInit parameters from the start result.
  3. Invoke the FaceScan activity with serverSideFaceInit.sessionToken from the start result.
  4. Invoke the controller finish call with the result from the FaceScan .

For further details specific to the operation, see the relevant sub-chapters.

Activation

Activation will be supported in a future release. This means that currently, you must:

  1. Activate with PIN and/or biometrics.
  2. Use the Add or update operation to add face authentication.

AddOrUpdate

Start call

For an example of startAddOrUpdate, click to expand the collapsible section:

Click to expand
private lateinit var context: Context
private lateinit var controller: Controller
private var startAddOrUpdateResult: StartAddOrUpdateResult? = null

fun startAddOrUpdate() {
//
// 1. Invoke the controller start call
//
controller.startAddOrUpdate(StartAddOrUpdateParameter(DEVICE_SERVER_SIDE_FACE), object : AsyncCallback<StartAddOrUpdateResult> {

override fun onSuccess(result: StartAddOrUpdateResult) {

startAddOrUpdateResult = result

if (result.authMethodsForActivation.contains(DEVICE_SERVER_SIDE_FACE) || result.authMethodsForAuthentication.contains(DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
val productionKeyText = result.serverSideFaceInit!!.productionKeyText
val deviceKeyIdentifier = result.serverSideFaceInit!!.deviceKeyIdentifier
val faceScanEncryptionKey = result.serverSideFaceInit!!.encryptionKey

FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey) { initializationSuccess ->

if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
}
}

override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display the error
}
})
}

Finish call

For examples, click to expand the collapsible sections:

  • finishAddOrUpdate(PIN, ServerSideFace):
    Click to expand
    fun finishAddOrUpdate() {
    // User accepted: Start FaceScan.

    //
    // 3. Invoke the FaceScan activity
    //
    val sessionToken = startAddOrUpdateResult!!.serverSideFaceInit!!.sessionToken

    FaceTecSessionActivity.createAndLaunchSession(context, FaceTecFaceScanProcessor { sessionResult, faceTecFaceScanResultCallback ->

    faceTecFaceScanResultCallback.cancel()

    if (sessionResult.status == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
    //
    // 4. Invoke the controller finish call with the result from the FaceScan.
    //
    controller.finishAddOrUpdate(DevicePinAuthParameter("1234"), DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncCallback<FinishAuthenticationResult> {

    override fun onSuccess(result: FinishAuthenticationResult) {
    // TODO - Display successfully added/activated server-side face
    }

    override fun onFailure(errorCodeException: ErrorCodeException) {
    // TODO - Display error message
    }
    })

    } else {
    // TODO - Display the error
    }
    }, sessionToken)
    }

    private fun createFaceScanData(sessionResult: FaceTecSessionResult): FaceScanData {
    return FaceScanData(
    sessionResult.faceScanBase64,
    sessionResult.auditTrailCompressedBase64[0],
    sessionResult.lowQualityAuditTrailCompressedBase64[0]
    )
    }
  • finishAddOrUpdate(ServerSideFace, PIN):
    Click to expand

    This flow is identical to the finishAddOrUpdate(PIN, ServerSideFace) flow, however the finishAddOrUpdate call has swapped parameters for PIN and server-side face:

    controller.finishAddOrUpdate(DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), DevicePinActivationParameter("1234"), object : AsyncStateChangedCallback<FinishAuthenticationResult> {
  • finishAddOrUpdate(BiomtricPrompt, ServerSideFace):
    Click to expand

    This flow is identical to the finishAddOrUpdate(PIN, ServerSideFace) flow, however but the finishAddOrUpdate call has DeviceAndroidBiometricPromptAuthParameter instead of DevicePinAuthParameter:

    controller.finishAddOrUpdate(DeviceAndroidBiometricPromptAuthParameter(context), DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncStateChangedCallback<FinishAuthenticationResult> {
  • finishAddOrUpdate(ServerSideFace, BiomtricPrompt):
    Click to expand

    This flow is identical to the finishAddOrUpdate(PIN, ServerSideFace) flow, however the finishAddOrUpdate call has DeviceAndroidBiometricPromptActivationParameter instead of DevicePinActivationParameter:

    controller.finishAddOrUpdate(DeviceServerSideFaceAuthParameter(createFaceScanData(sessionResult)), DeviceAndroidBiometricPromptActivationParameter(context), object : AsyncStateChangedCallback<FinishAuthenticationResult> {

Authentication

Start call

For an example of startAuthentication, click to expand the collapsible section:

Click to expand
private lateinit var context: Context
private lateinit var controller: Controller
private var startAuthenticationResult: StartAuthenticationResult? = null

fun startAuthentication() {
//
// 1. Invoke the controller start call
//
controller.startAuthentication(object : AsyncCallback<StartAuthenticationResult> {

override fun onSuccess(result: StartAuthenticationResult) {

startAuthenticationResult = result

if (result.authMethodsForAuthentication.contains(AuthMethod.DEVICE_SERVER_SIDE_FACE)) {
//
// 2. Initialise the FaceScan library
//
val productionKeyText = result.serverSideFaceInit!!.productionKeyText
val deviceKeyIdentifier = result.serverSideFaceInit!!.deviceKeyIdentifier
val faceScanEncryptionKey = result.serverSideFaceInit!!.encryptionKey

FaceTecSDK.initializeInProductionMode(context, productionKeyText, deviceKeyIdentifier, faceScanEncryptionKey) { initializationSuccess ->

if (initializationSuccess) {
// TODO - Display message to user: Start FaceScan?
} else {
// TODO - Display the error
}
}
}
}

override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display the error
}
})
}

Finish call

For an example of finishAuthentication(ServerSideFace), click to expand the collapsible section:

Click to expand
fun finishAuthentication() {
// User has accepted: Start FaceScan.

//
// 3. Invoke the FaceScan activity
//
val sessionToken = startAuthenticationResult!!.serverSideFaceInit!!.sessionToken

FaceTecSessionActivity.createAndLaunchSession(context, FaceTecFaceScanProcessor { sessionResult, faceTecFaceScanResultCallback ->

faceTecFaceScanResultCallback.cancel()

if (sessionResult.status == FaceTecSessionStatus.SESSION_COMPLETED_SUCCESSFULLY) {
//
// 4. Invoke the controller finish call with the result from the FaceScan.
//
controller.finishAuthentication(DeviceServerSideFaceActivationParameter(createFaceScanData(sessionResult)), object : AsyncCallback<FinishAuthenticationResult> {

override fun onSuccess(result: FinishAuthenticationResult) {
// TODO - Display successfully added/activated server-side face
}

override fun onFailure(errorCodeException: ErrorCodeException) {
// TODO - Display error message
}

})

} else {
// TODO - Display the error
}
}, sessionToken)
}

private fun createFaceScanData(sessionResult: FaceTecSessionResult): FaceScanData {
return FaceScanData(
sessionResult.faceScanBase64,
sessionResult.auditTrailCompressedBase64[0],
sessionResult.lowQualityAuditTrailCompressedBase64[0]
)
}

Error handling

The following client-side errors originate in the FaceTec SDK, and are propagated as follows:

  • FaceTecSDK.initializeInProductionMode() returns errors in FaceTecSDK.getStatus(context).
  • FaceTecSessionActivity.createAndLaunchSession() returns errors in sessionResult.getStatus(), in the callback method processSessionWhileFaceTecSDKWaits(FaceTecSessionResult sessionResult).

Localisation

The FaceTecSDK includes language resource strings prefixed with FaceTec_. It supports the following languages:

  • Afrikaans (af)
  • Arabic (ar)
  • German (de)
  • Greek (el)
  • English (en)
  • Spanish (es)
  • French (fr)
  • Kazakh (kk)
  • Norwegian (nb)
  • Portuguese (pt-rBR)
  • Russian (ru)

For further details, see the FaceTecSDK.zip file.

Branding and styling

What elements can be customised?

The FaceTec SDK allows you to customise various branding and styling elements, such as:

  • Interface
  • Borders
  • Colors
  • Fonts
  • Branding image
  • Button image and position
  • Progress
  • Vocal guidance sound file resources

To learn more about what you can customise, see the UX Themes Branding page in the FaceTec documentation. You can also refer to the FaceTecSDK.zip file.

How to customise the configuration

To make changes, you have to create a FaceTecCustomization object, where you define each field that you want to change.

Different environmental conditions

You can apply different settings based on environmental conditions, such as low-light or bright-light situations.

To do this, you must set a unique configuration for each of the scenarios using the FaceTecCustomization object.

The FaceTecSDK includes methods:

  • Default:
    Example: Default method
    FaceTecSDK.setCustomization(customization: FaceTecCustomization)
  • Low-light:
    Example: Low-light method
    FaceTecSDK.setLowLightCustomization(customization: FaceTecCustomization)
  • Bright-light:
    Example: Bright-light method
    FaceTecSDK.setDynamicDimmingCustomization(customization: FaceTecCustomization)

Multiple controller scenario

For a multiple controller scenario, face authentication must be activated for each controller.