Authenticate user with biometrics
Introduction
Biometric Authentication allows users to perform authentication by using biometrics such as fingerprint or face recognition. The biggest gain of enabling Biometric Authentication is the improved end-users experience. Users are now enabled to access their sensitive data or authenticate transactions using Android's common biometric validation.
The SDK allows you to authenticate users with the biometric features of user's device. You can use it for both regular authentication as well as mobile authentication. Users will be able to attempt biometric scanning as many times as the Android system will allow them to. If Android Biometric API will return an error for any reason (for example when too many failed attempts was detected), the SDK will revoke biometric authentication and perform a fallback to PIN authentication.
It's important to mention that only Class 3 biometric (as defined by Android) can be used to authenticate users. This means that for example simple face recognition offered by many devices doesn't classify as a strong (Class 3) biometric authenticator, thus cannot be used with cryptographic solutions. Device manufacturer's biometic implementation has to meet Google's strict security requirements to be considered a strong authenticator.
Availability
A User can enable fingerprint authentication only if all of the following requirements are met:
- the device is not rooted
- the device has Class 3 hardware biometric reader
- the user has already enrolled biometrics on the device (i.e. registered at least one fingerprint)
- the client configuration on the Server allows use of fingerprint authentication
Root detection
The root detection check is applied during the biometric authentication, even if root detection is disabled for the application itself. The reason is that rooted devices are more vulnerable, as the application sandbox as well as AndroidKeystore can be violated. The situation is even more serious for clients who are not using tampering protection.
Biometrics changes
As explained in google docs keys stored in the AndroidKeyStore will become permanently invalidated once a new biometric enrollment is added or all enrollments are removed. In such case, the SDK will deregister biometric authenticator and the user will have to enroll for biometric authentication again.
Using biometric authentication with multiple user profiles
The Android SDK v5.03.00 introduced support for multiple user profiles. When this feature is implemented, an end-user will be able to create and use different accounts (profiles) on the same device. Each profile has it's own separated PIN, push notification support and other features. However, as stated above, the Android Biometric API was designed with the assumption that a device is being used by only one person. This person can have multiple biometric enrollments, but from the API perspective they all belong to the same person. In particular, if a device is being shared between multiple people and all of them will register biometrics, the API is not able to distinguish whom of them performed authentication.
Because of this, if the application supports both the multiple profiles feature and biometric authentication, you should keep in mind, that it has some (potential) drawbacks. Let's assume that Bob is the owner of a device, but he shares it with his wife Alice. They have both registered their fingerprints and they both created profile in the ExampleApp.
- When the ExampleApp asks Bob for a fingerprint for login or to confirm a transaction, any valid (registered) fingerprint will be accepted. Because of that Alice can login to Bob's account using her fingerprint.
- When Bob tries to authenticate with a fingerprint but the exceeds number of failed attempts, the Android Biometric API can be blocked automatically for some amount of time (around 15-30 seconds). If Alice will try to log in to her account shortly after that, she might not be able to do so before the API will be unblocked.
- When the Server detects improper usage of a biometric refresh token that indicates a corrupted or modified biometric keystore - all biometric refresh tokens on this device will be revoked on the server side.
Authenticate using Biometric Authentication
Whenever biometric authentication is enabled and the device is not rooted the user will be prompt to scan his/her finger instead of providing his/her PIN in order to authenticate. The SDK will use OneginiBiometricAuthenticationRequestHandler
interface to ask for a fingerprint. The handler should show a Biometric Prompt and include BiometricPrompt.CryptoObject
provided by the handler. CryptoObject is used for cryptography purposes and allows SDK to use biometric refresh token to authenticate user on Server.
Due to the fact that biometric scanning is not perfect (e.g. the user may have wet or dirty hands, also the temperature may impact the scan result) the user can always choose to fallback on PIN authentication. This can be done by calling OneginiBiometricCallback#fallbackToPin()
method.
Also, after failing to scan a fingerprint for the allowed number of times, the SDK will automatically fallback on the PIN authentication method. If the user will not be able to provide a valid PIN within the allowed number of times, he will be deregistered.
Enabling biometric authentication
In order to enable biometric authentication for user you need to request a list of not yet registered authenticators with UserClient.getNotRegisteredAuthenticators(final UserProfile userProfile)
. This method can be used after user is authenticated and will return a set of OneginiAuthenticator
that are possible to register. Then you can register chosen authenticator providing the authenticator's instance to UserClient.registerAuthenticator(final
OneginiAuthenticator authenticator, final
OneginiAuthenticatorRegistrationHandler handler)
method, along
with the handler that will inform you about success or failure of the
registration process. If your device haven't met one of the requirements, the biometric authenticator won't be present on the list of authenticators.
Example code for registering a biometric authenticator
Note that registering a new authenticator doesn't make it a preferred
authenticator to be used. By default preferred authenticator is PIN, so
if you want to
change it, you need to inform the SDK about it with UserClient.setPreferredAuthenticator(final OneginiAuthenticator authenticator)
providing any registered
authenticator.
Please note that CustomInfo is an optional param that will be always null during biometric authenticator registration.
Disabling Biometric Authentication
To disable biometric authentication for currently authenticated user profile, call deregisterAuthenticator(final OneginiAuthenticator authenticator, final OneginiAuthenticatorDeregistrationHandler handler)
on the UserClient
instance. The method will revoke user's biometric refresh token on
both client and server side. User will still be able to login using his
PIN.
Authentication handlers
The SDK provides two interfaces (OneginiBiometricAuthenticationRequestHandler
and OneginiMobileAuthWithPushBiometricRequestHandler
for
respectively: regular and push authentication) that you can implement in
your application to use the biometric authentication. Later you will
need to provide
them to OneginiClientBuilder
instance as shown below:
OneginiBiometricAuthenticationRequestHandler
interface exposes two methods that are used to control the process of biometric authentication:
startAuthentication(final UserProfile userProfile, BiometricPrompt.CryptoObject cryptoObject, final OneginiBiometricCallback callback)
triggered when a new fingerprint authentication request is made, providing anUserProfile
object, biometric crypto object that has to be authenticated and a biometric callback;finishAuthentication()
triggered when biometric authentication finished either with success or an error.
OneginiMobileAuthWithPushFingerprintRequestHandler
works in exactly the same manner with a single change in parameters of startAuthentication()
method, where instead of the UserProfile
you get the OneginiMobileAuthenticationRequest
object containing information about the push request as well as UserProfile
. You can read more about mobile biometric authentication in mobile authentication with PUSH topic guide.
Example code for OneginiBiometricAuthenticationRequestHandler implementation
OneginiBiometricCallback
To control the flow of biometric authentication you should use provided OneginiBiometricCallback
callback. It consists of four methods:
userAuthenticatedSuccessfully()
that should be called when user successfully authenticated using Biometric Prompt,denyAuthenticationRequest
which should be triggered when user denies the biometric authentication request.fallbackToPin
that should be invoked when user decides to resign from biometric authentication and wants to enter his PIN to finish authentication.onBiometricAuthenticationError(final int errorCode)
that should be called when Biometric Prompt returned an error.errorCode
parameter represents the code returned from the Biometric Prompt. Based on the code SDK will perform necessary actions i.e. when abuse is detected biometric authenticator will be deregistered for all users.
In the example code above you should use the static instance of OneginiBiometricCallback
in the BiometricActivity
to react on user actions. Same applies to instance of BiometricPrompt.CryptoObject
which should be passed to the BiometricPrompt before showing it to the user.
Showing Biometric Prompt
Onegini SDK depends on the
androidx.biometric:biometric
library to provide this functionality. When implementingBiometricPrompt
it's important to import classes fromandroidx.biometric
package and not fromandroid.hardware.biometrics
. For the library version used by the SDK please check third party libraries section
Biometric Prompt introduced several advantages over it's predecessor the Fingerprint Manager:
- Biometric Prompt provides a standardized system for requesting biometric authentication, ensuring compatibility across various Android devices and versions. It supports not only fingerprint recognition but also other biometric modalities like facial recognition and iris scanning.
- Biometric Prompt offers a more secure framework by not directly exposing biometric authentication to apps. It requires explicit user consent and authenticates the user within a secure isolated environment, keeping the biometric data more protected.
- It offers a consistent user interface for biometric authentication across different devices and manufacturers, creating a seamless experience for users regardless of the device they're using.
- It's designed to support upcoming biometric authentication methods, allowing for easy integration of new biometric technologies that may emerge in the future, ensuring the framework remains up-to-date and adaptable.
- Developers can customize the prompt and change the title, subtitle and negative button texts displayed to the user.
To perform biometric authentication you first need to build PromptInfo
with correct parameters:
Next step is to show the prompt to the user:
In the authenticate
method of the BiometricPrompt
you need to provide previously built PromptInfo
object as well as the BiometricPrompt.CryptoObject
you received in the OneginiBiometricAuthenticationRequestHandler.startAuthentication(final UserProfile userProfile, BiometricPrompt.CryptoObject cryptoObject, final OneginiBiometricCallback callback)
method.
BiometricPrompt
required also a callback object in which you will receive authentication result. This result needs to be passed back to Onegini SDK via OneginiBiometricCallback
to finish the process.
It is important to also pass error result back to Onegini SDK, so it can act accordingly and finish the authentication process.
You can find more details about BiometricPrompt
in official Android documentation.