public void EnableBiometrics(Action <bool> callback) { var passwordStorage = new PasswordStorageManager(this); var executor = ContextCompat.GetMainExecutor(this); var authCallback = new AuthenticationCallback(); authCallback.Success += async(_, result) => { try { var password = await SecureStorageWrapper.GetDatabasePassword(); passwordStorage.Store(password, result.CryptoObject.Cipher); } catch (Exception e) { Logger.Error(e); callback(false); return; } callback(true); }; authCallback.Failed += delegate { callback(false); }; authCallback.Error += delegate { // Do something, probably callback(false); }; var prompt = new BiometricPrompt(this, executor, authCallback); var promptInfo = new BiometricPrompt.PromptInfo.Builder() .SetTitle(GetString(Resource.String.setupBiometricUnlock)) .SetNegativeButtonText(GetString(Resource.String.cancel)) .SetConfirmationRequired(false) .SetAllowedAuthenticators(BiometricManager.Authenticators.BiometricStrong) .Build(); Cipher cipher; try { cipher = passwordStorage.GetEncryptionCipher(); } catch (Exception e) { Logger.Error(e); passwordStorage.Clear(); callback(false); return; } prompt.Authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher)); }
public void Authenticate(Func <Task> action, string title) { try { switch (BiometricManager.From(_context).CanAuthenticate()) { case BiometricManager.BiometricSuccess: var biometricPrompt = new BiometricPrompt(MainActivity, ContextCompat.GetMainExecutor(_context), GetBiometricAuthenticationCallback(action)); var promptInfo = new BiometricPrompt.PromptInfo.Builder() .SetTitle(title == null ? "Biometric login for Falcon" : $"{title}...") .SetNegativeButtonText("Cancel") .Build(); biometricPrompt.Authenticate(promptInfo); return; case BiometricManager.BiometricErrorHwUnavailable: Tools.DisplayAlert(message: "Biometric hardware is currently unavailable. Try again later."); return; case BiometricManager.BiometricErrorNoneEnrolled: Tools.DisplayAlert(message: "The device does not have any biometrics enrolled. Please make sure you have set up any available biometrics in your phone Settings."); return; default: return; } } catch (Exception ex) { //DisplayAlertError("Something went wrong while using biometric authentication."); } }
protected override async Task <FingerprintAuthenticationResult> NativeAuthenticateAsync(AuthenticationRequestConfiguration authRequestConfig, CancellationToken cancellationToken) { if (string.IsNullOrWhiteSpace(authRequestConfig.Title)) { throw new ArgumentException("Title must not be null or empty on Android.", nameof(authRequestConfig.Title)); } if (!(CrossFingerprint.CurrentActivity is FragmentActivity)) { throw new InvalidOperationException($"Expected current activity to be '{typeof(FragmentActivity).FullName}' but was '{CrossFingerprint.CurrentActivity?.GetType().FullName}'. " + "You need to use AndroidX. Have you installed Xamarin.AndroidX.Migration in your Android App project!?"); } try { var cancel = string.IsNullOrWhiteSpace(authRequestConfig.CancelTitle) ? Application.Context.GetString(Android.Resource.String.Cancel) : authRequestConfig.CancelTitle; var handler = new AuthenticationHandler(); var builder = new BiometricPrompt.PromptInfo.Builder() .SetTitle(authRequestConfig.Title) .SetConfirmationRequired(authRequestConfig.ConfirmationRequired) .SetDescription(authRequestConfig.Reason); if (authRequestConfig.AllowAlternativeAuthentication) { // It's not allowed to allow alternative auth & set the negative button builder = builder.SetDeviceCredentialAllowed(authRequestConfig.AllowAlternativeAuthentication); } else { builder = builder.SetNegativeButtonText(cancel); } var info = builder.Build(); var executor = Executors.NewSingleThreadExecutor(); var activity = (FragmentActivity)CrossFingerprint.CurrentActivity; using var dialog = new BiometricPrompt(activity, executor, handler); await using (cancellationToken.Register(() => dialog.CancelAuthentication())) { dialog.Authenticate(info); var result = await handler.GetTask(); TryReleaseLifecycleObserver(activity, dialog); return(result); } } catch (Exception e) { return(new FingerprintAuthenticationResult { Status = FingerprintAuthenticationResultStatus.UnknownError, ErrorMessage = e.Message }); } }
private void ShowBiometricPrompt() { var executor = ContextCompat.GetMainExecutor(Context); var passwordStorage = new PasswordStorageManager(Context); var callback = new AuthenticationCallback(); callback.Succeeded += (_, result) => { string password; try { password = passwordStorage.Fetch(result.CryptoObject.Cipher); } catch (Exception e) { Logger.Error(e); Toast.MakeText(Context, Resource.String.genericError, ToastLength.Short); return; } UnlockAttempted?.Invoke(this, password); }; callback.Failed += delegate { FocusPasswordText(); }; callback.Errored += (_, result) => { Toast.MakeText(Context, result.Message, ToastLength.Short).Show(); FocusPasswordText(); }; _prompt = new BiometricPrompt(this, executor, callback); var promptInfo = new BiometricPrompt.PromptInfo.Builder() .SetTitle(GetString(Resource.String.unlock)) .SetSubtitle(GetString(Resource.String.unlockBiometricsMessage)) .SetNegativeButtonText(GetString(Resource.String.cancel)) .SetConfirmationRequired(false) .SetAllowedAuthenticators(BiometricManager.Authenticators.BiometricStrong) .Build(); try { var cipher = passwordStorage.GetDecryptionCipher(); _prompt.Authenticate(promptInfo, new BiometricPrompt.CryptoObject(cipher)); } catch (Exception e) { Logger.Error(e); _canUseBiometrics = false; _useBiometricsButton.Enabled = false; FocusPasswordText(); } }
public void StartListening(BiometricPrompt.AuthenticationCallback callback) { Kp2aLog.Log("Fingerprint: StartListening "); var executor = Executors.NewSingleThreadExecutor(); _biometricPrompt = new BiometricPrompt(_activity, executor, callback); BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() .SetTitle(_activity.GetString(AppNames.AppNameResource)) .SetSubtitle(_activity.GetString(Resource.String.unlock_database_title)) .SetNegativeButtonText(_activity.GetString(Android.Resource.String.Cancel)) .SetConfirmationRequired(false) .Build(); _biometricPrompt.Authenticate(promptInfo, _cryptoObject); }
private void ShowBiometricPrompt(Java.Security.Signature signature) { // Create biometric prompt var activity = MainActivity.FormsContext; var negativeButtonListener = new DialogInterfaceOnClickListener(() => { // Do something here. }); biometricPrompt = new BiometricPrompt.Builder(activity) .SetDescription("Never Been Easier") .SetTitle("Biometric Prompt Authentication") .SetSubtitle("Please allow Xamarin Life to authenticate") .SetNegativeButton("Cancel", activity.MainExecutor, negativeButtonListener) .Build(); // Show biometric prompt var cancellationSignal = new CancellationSignal(); var authenticationCallback = GetAuthenticationCallback(); biometricPrompt.Authenticate(new BiometricPrompt.CryptoObject(signature), cancellationSignal, activity.MainExecutor, authenticationCallback); }
public void Authenticate(string userId, Action onSuccess, Action onFailure) { OnSuccess = onSuccess; OnFailure = onFailure; if (IsBiometricPromptEnabled) { newCancelSignal = new Android.OS.CancellationSignal(); prompt = new BiometricPrompt.Builder(CrossCurrentActivity.Current.Activity) .SetTitle("ManageGo") .SetSubtitle("Fingerprint Login") .SetDescription($"Place finger on the home button to log in as {userId}") .SetNegativeButton("CANCEL", CrossCurrentActivity.Current.Activity.MainExecutor, new DialogListener(this)).Build(); prompt.Authenticate(newCancelSignal, CrossCurrentActivity.Current.Activity.MainExecutor, new BiometricCallback(this)); } else { cancellationSignal = new Android.Support.V4.OS.CancellationSignal(); var callback = new SimpleAuthCallbacks(this); FingerprintManager.Authenticate(null, 0, cancellationSignal, callback, null); } }
private async Task <BiometricPrompt.AuthenticationResult> AuthenticateAndProcess(CancellationToken ct, string keyName, BiometricPrompt.CryptoObject crypto = null) { if (this.Log().IsEnabled(LogLevel.Debug)) { this.Log().Debug($"Authenticating and processing the fingerprint (key name: '{keyName}')."); } int result = 0; if (Android.OS.Build.VERSION.SdkInt <= Android.OS.BuildVersionCodes.Q) { result = _biometricManager.CanAuthenticate(); } else { result = _biometricManager.CanAuthenticate(BiometricManager.Authenticators.BiometricStrong); } if (result == BiometricManager.BiometricSuccess) { _authenticationCompletionSource = new TaskCompletionSource <BiometricPrompt.AuthenticationResult>(); // Prepare and show UI var prompt = await _promptInfoBuilder(ct); await _dispatcher.RunAsync(CoreDispatcherPriority.High, () => { try { if (crypto == null) { _biometricPrompt.Authenticate(prompt); } else { _biometricPrompt.Authenticate(prompt, crypto); } } catch (System.Exception e) { _authenticationCompletionSource.TrySetException(e); } }); var authenticationTask = _authenticationCompletionSource.Task; await Task.WhenAny(authenticationTask); if (authenticationTask.IsCompletedSuccessfully && this.Log().IsEnabled(LogLevel.Information)) { this.Log().Info($"Successfully authenticated and processed the fingerprint (key name: '{keyName}')."); } if (authenticationTask.IsCanceled) { throw new OperationCanceledException(); } return(authenticationTask.Result); } else { if (result == BiometricManager.BiometricErrorNoneEnrolled) { throw new InvalidOperationException("No fingerprint(s) registered."); } else { if (this.Log().IsEnabled(LogLevel.Warning)) { this.Log().Warn($"Fingerprint authentication is not available."); } throw new NotSupportedException("Fingerprint authentication is not available."); } } }