/// <summary> /// Authenticate the user using biometrics. /// </summary> /// <param name="ct">The <see cref="CancellationToken" /> to use.</param> /// <returns>A <see cref="BiometryResult" /> enum value.</returns> public async Task <BiometryResult> ValidateIdentity(CancellationToken ct) { var context = new LAContext(); context.LocalizedReason = _options.LocalizedReasonBodyText; context.LocalizedFallbackTitle = _options.LocalizedFallbackButtonText; context.LocalizedCancelTitle = _options.LocalizedCancelButtonText; var capabilities = await GetCapabilities(); if (!capabilities.PasscodeIsSet) { throw new Exception( "No passcode/password is set on the device. To avoid catching this exception: call GetCapabilities() and inspect if the passcode/password is set or not before calling this method."); } if (!capabilities.IsSupported) { throw new Exception( "Biometrics not available (no hardware support OR user has disabled FaceID/TouchID for the app). To avoid catching this exception: call GetCapabilities() and inspect if the biometrics is supported before calling this method."); } if (!capabilities.IsEnabled) { throw new Exception( "Biometrics not enrolled (no finger xor face was added by the user). To avoid catching this exception: call GetCapabilities() and inspect if biometrics is enabled before calling this method."); } if (context.BiometryType == LABiometryType.FaceId) { // Verify that info.plist contains NSFaceIDUsageDescription key/value otherwise the app will crash var faceIDUsageDescription = ((NSString)NSBundle.MainBundle.InfoDictionary["NSFaceIDUsageDescription"])?.ToString(); if (string.IsNullOrEmpty(faceIDUsageDescription)) { throw new BiometryException(0, "Please add a NSFaceIDUsageDescription key in the `Info.plist` file."); } } var(_, laError) = await context.EvaluatePolicyAsync(_localAuthenticationPolicy, context.LocalizedReason); var evaluatePolicyResult = GetAuthenticationResultFrom(laError); var result = new BiometryResult(); switch (evaluatePolicyResult) { case BiometryAuthenticationResult.Granted: result.AuthenticationResult = BiometryAuthenticationResult.Granted; break; case BiometryAuthenticationResult.Cancelled: result.AuthenticationResult = BiometryAuthenticationResult.Cancelled; break; case BiometryAuthenticationResult.Denied: result.AuthenticationResult = BiometryAuthenticationResult.Denied; break; } return(result); }
/// <summary> /// Validate the user identity. /// </summary> /// <param name="ct">The <see cref="CancellationToken" /> to use.</param> /// <returns>A <see cref="BiometryResult" /> enum value.</returns> public async Task <BiometryResult> ValidateIdentity(CancellationToken ct) { using (await _asyncLock.LockAsync(ct)) { var response = await AuthenticateAndProcess(ct, CRYPTO_OBJECT_KEY_NAME); var result = new BiometryResult(); if (response.AuthenticationType == 0) //BiometryAuthenticationResult.Granted { result.AuthenticationResult = BiometryAuthenticationResult.Granted; } else if (response.AuthenticationType == 1) //BiometryAuthenticationResult.Denied { result.AuthenticationResult = BiometryAuthenticationResult.Denied; } else if (response.AuthenticationType == 2) //BiometryAuthenticationResult.Cancelled { result.AuthenticationResult = BiometryAuthenticationResult.Cancelled; } return(result); } }