/// <summary> /// Bespoke method to use touch ID (or iPhone 10 FaceID) /// </summary> private void BiometricsAuth() { // throw new NotImplementedException(); NSError error; var context = new LAContext(); // LA Local Authentication - must declare a context for authentication (d'tell us about device capabilities &c) if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out error)) // can current device use biometrics? { // NB Local Authentication MUST be performed on the app's main thread https://developer.apple.com/documentation/localauthentication/logging_a_user_into_your_app_with_face_id_or_touch_id // Anonymous function defined for local authentication, which must be async to await EvaluatePolicyAsync InvokeOnMainThread(async() => { var result = await context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Login"); if (result.Item1) // if on-device local biometric authentication has OK'd the user (get tuple's Item1 https://docs.microsoft.com/en-us/dotnet/api/system.tuple-1.item1?view=netframework-4.8) { hasLoggedIn = true; PerformSegue("tabSegue", this); // once signed-in, navigate to TabsActivity with Delivered/Waiting &c tabs } else { ServerLogin(); // if user not OK'd biometrically, check credentials on server } }); } else { // If biometric local authentication not available, check credentials on server db ServerLogin(); } }
private async Task BiometricsAuth() { var context = new LAContext(); if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out _)) { InvokeOnMainThread(async() => { var authenticated = await context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Login"); if (authenticated.Item1) { _hasLoggedIn = true; PerformSegue("LoginSegue", this); } else { await TraditionalLogin(); } }); } else { await TraditionalLogin(); } }
protected override async Task <FingerprintAuthenticationResult> NativeAuthenticateAsync(AuthenticationRequestConfiguration authRequestConfig, CancellationToken cancellationToken = new CancellationToken()) { var result = new FingerprintAuthenticationResult(); SetupContextProperties(authRequestConfig); Tuple <bool, NSError> resTuple; using (cancellationToken.Register(CancelAuthentication)) { var policy = GetPolicy(authRequestConfig.AllowAlternativeAuthentication); resTuple = await _context.EvaluatePolicyAsync(policy, authRequestConfig.Reason); } if (resTuple.Item1) { result.Status = FingerprintAuthenticationResultStatus.Succeeded; } else { // #79 simulators return null for any reason if (resTuple.Item2 == null) { result.Status = FingerprintAuthenticationResultStatus.UnknownError; result.ErrorMessage = ""; } else { result = GetResultFromError(resTuple.Item2); } } CreateNewContext(); return(result); }
private void BiometricsAuth() { NSError error; var context = new LAContext(); if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out error)) { InvokeOnMainThread(async() => { var result = await context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Login"); if (result.Item1) { hasLoggedIn = true; PerformSegue("loginSegue", this); } else { TraditionalLogin(); } }); } else { TraditionalLogin(); } }
private void BiometricAuth() { NSError error; var contxt = new LAContext(); if (contxt.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out error)) { InvokeOnMainThread(async() => { var canLogin = await contxt.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Login"); if (canLogin.Item1) { isLogged = true; PerformSegue("sgeLogin", this); } else { NormalLogin(); } }); } else { NormalLogin(); } }
/// <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); }
protected override async Task <FingerprintAuthenticationResult> NativeAuthenticateAsync(AuthenticationRequestConfiguration authRequestConfig, CancellationToken cancellationToken = new CancellationToken()) { var result = new FingerprintAuthenticationResult(); SetupContextProperties(authRequestConfig); Tuple <bool, NSError> resTuple; using (cancellationToken.Register(CancelAuthentication)) { var policy = GetPolicy(authRequestConfig.AllowAlternativeAuthentication); resTuple = await _context.EvaluatePolicyAsync(policy, authRequestConfig.Reason); } if (resTuple.Item1) { result.Status = FingerprintAuthenticationResultStatus.Succeeded; } else { switch ((LAStatus)(int)resTuple.Item2.Code) { case LAStatus.AuthenticationFailed: var description = resTuple.Item2.Description; if (description != null && description.Contains("retry limit exceeded")) { result.Status = FingerprintAuthenticationResultStatus.TooManyAttempts; } else { result.Status = FingerprintAuthenticationResultStatus.Failed; } break; case LAStatus.UserCancel: case LAStatus.AppCancel: result.Status = FingerprintAuthenticationResultStatus.Canceled; break; case LAStatus.UserFallback: result.Status = FingerprintAuthenticationResultStatus.FallbackRequested; break; case LAStatus.TouchIDLockout: result.Status = FingerprintAuthenticationResultStatus.TooManyAttempts; break; default: result.Status = FingerprintAuthenticationResultStatus.UnknownError; break; } result.ErrorMessage = resTuple.Item2.LocalizedDescription; } CreateNewContext(); return(result); }
public override void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. authenticationButton.TouchUpInside += (sender, e) => { var context = new LAContext(); var result = context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthentication, "Authentication Request").GetAwaiter().GetResult(); var can = context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out Foundation.NSError error); if (result.Item1) { UserDialogs.Instance.Alert("Authentication"); } else { var code = Convert.ToInt16(result.Item2.Code); var status = (LAStatus)code; UserDialogs.Instance.Alert(status.ToString()); } }; authenButton.TouchUpInside += (sender, e) => { var context = new LAContext(); var myReason = new NSString("To add a new chore"); if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out NSError AuthError)) { var replyHandler = new LAContextReplyHandler((success, error) => { this.InvokeOnMainThread(() => { if (success) { UserDialogs.Instance.Alert("Login Success"); } else { //Show fallback mechanism here } }); }); context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, myReason, replyHandler); } ; }; }
public async Task <FingerprintAuthenticationResult> AuthenticateAsync(string reason, CancellationToken cancellationToken) { var result = new FingerprintAuthenticationResult(); cancellationToken.Register(CancelAuthentication); if (!IsAvailable) { result.Status = FingerprintAuthenticationResultStatus.NotAvailable; return(result); } var resTuple = await _context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, reason); if (resTuple.Item1) { result.Status = FingerprintAuthenticationResultStatus.Succeeded; } else { switch ((LAStatus)(int)resTuple.Item2.Code) { case LAStatus.AuthenticationFailed: result.Status = FingerprintAuthenticationResultStatus.Failed; break; case LAStatus.UserCancel: result.Status = FingerprintAuthenticationResultStatus.Canceled; break; case LAStatus.UserFallback: result.Status = FingerprintAuthenticationResultStatus.FallbackRequested; break; default: result.Status = FingerprintAuthenticationResultStatus.UnknownError; break; } result.ErrorMessage = resTuple.Item2.LocalizedDescription; } return(result); }
/// <summary> /// Auths the on main thread. /// </summary> /// <returns>The on main thread.</returns> /// <param name="context">Context.</param> /// <param name="reason">Reason can not be null or empty</param> private Task <LocalAuthResult> AuthOnMainThreadAsync(LAContext context, string reason) { var tcs = new TaskCompletionSource <LocalAuthResult>(); var result = new LocalAuthResult(false); /* ================================================================================================== * indicate not allow null or empty reason * ================================================================================================*/ if (string.IsNullOrWhiteSpace(reason)) { result = new LocalAuthResult(false, "Your reason can not be null or empty"); tcs.SetResult(result); return(tcs.Task); } /* ================================================================================================== * indicate the hardware * ================================================================================================*/ if (!context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out NSError authError)) { result = new LocalAuthResult(false, authError?.ToString()); tcs.SetResult(result); return(tcs.Task); } /* ================================================================================================== * begin auth * ================================================================================================*/ var nsReason = new NSString(reason); var evaluateTask = context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, nsReason); evaluateTask.ContinueWith(t => { Device.BeginInvokeOnMainThread(() => { var rs = t.Result; result = new LocalAuthResult(rs.Item1, rs.Item2?.ToString()); tcs.SetResult(result); }); }); return(tcs.Task); }
public async Task <bool> Authenticate(CancellationToken ct) { if (this.Log().IsEnabled(LogLevel.Debug)) { this.Log().Debug("Authenticating the fingerprint."); } await AssertTouchIdIsEnabled(ct); using (await _asyncLock.LockAsync(ct)) { var context = new LAContext(); // Using LAPolicy.DeviceOwnerAuthentication will make authentication fallback on the passcode if touch id fails. var authenticationPolicy = _fallbackOnPasscodeAuthentication ? LAPolicy.DeviceOwnerAuthentication : LAPolicy.DeviceOwnerAuthenticationWithBiometrics; // Must call CanEvaluatePolicy before LAContext.BiometryType can be read var canEvaluatePolicy = context.CanEvaluatePolicy(authenticationPolicy, out NSError error); if (canEvaluatePolicy && context.BiometryType == LABiometryType.FaceId) { // Verify that info.plist Contains NSFaceIDUsageDescription otherwise the app will crash when it tries to authenticate string faceIDUsageDescription = ((NSString)NSBundle.MainBundle.InfoDictionary["NSFaceIDUsageDescription"])?.ToString(); if (string.IsNullOrEmpty(faceIDUsageDescription)) { throw new MissingFieldException("Please add a NSFaceIDUsageDescription key in Info.plist"); } } var(result, _) = await context.EvaluatePolicyAsync(authenticationPolicy, await _description(ct)); if (this.Log().IsEnabled(LogLevel.Information)) { this.Log().Info("Successfully authenticated the fingerprint."); } return(result); } }
public static async System.Threading.Tasks.Task Authenticate(DialogConfiguration dialogConfiguration) { _context = new LAContext(); _context.InvokeOnMainThread(async() => { var result = await _context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthentication, Configuration.DefaultFailAttemptNumberExceededMsg); bool success = result.Item1; NSError error = result.Item2; if (success) { dialogConfiguration.SuccessAction?.Invoke(); } else { if (error.Code == -2) { //user cancel return; } else if (error.Code == -1) { //too many failed attempt dialogConfiguration.FailedAction?.Invoke(); } } }); //NSError AuthError; //if (_context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out AuthError)) //{ // Tuple<bool, NSError> result = await _context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, dialogConfiguration.DialogDescription); // bool success = result.Item1; // NSError error = result.Item2; // if (result.Item1 == true) // dialogConfiguration.SuccessAction?.Invoke(); // else // { // if (error.Code == -2) // { // //User cancel // return; // }else if(error.Code == -1) // { // } // //if (error.LocalizedDescription == "Fallback authentication mechanism selected.") // //{ // // var s = error.Code; // // result = await _context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthentication, descrptionMessage); // // if (result.Item1) // // successAction?.Invoke(); // //} // } //} //else //{ // _context.InvokeOnMainThread(async () => // { // var result = await _context.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthentication, Configuration.DefaultFailAttemptNumberExceededMsg); // if (result.Item1) // dialogConfiguration.SuccessAction?.Invoke(); // }); //} }
public override async void ViewDidLoad() { base.ViewDidLoad(); Console.WriteLine("N0rf3n - ViewDidLoad - Begin"); try { Console.WriteLine("N0rf3n - ViewDidLoad - Begin/Try"); var Verifica = new LAContext(); //Context var myReason = new NSString("Autenticación Biométrica"); var autoriza = await Verifica.EvaluatePolicyAsync(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, //Await, es un proceso Asyncrono y toca cambiar el public override void por -> public override async void y vamos a usar la validación biometrica. myReason); if (autoriza.Item1) //el primer elemento Item1 hace refenrecia al OK y el segundo al error. { Console.WriteLine("N0rf3n - ViewDidLoad - Ingreso App - TouchID"); //Se establece todo el ancho y altura de la vista de la pantalla Altura = View.Bounds.Width; Ancho = View.Bounds.Height; AnchoCapaa = Altura / 2; Altura = Ancho / 6; CapaImagen = new CALayer(); //Se define una capa nueva. CapaImagen.Bounds = new CGRect(Altura / 2 - Ancho, Ancho / 2 - Altura / 2, AnchoCapaa, AlturaCapa); CapaImagen.Position = new CGPoint(100, 100); //Se establece una posición. CapaImagen.Contents = UIImage.FromFile("Tanjiro.jpg").CGImage; View.Layer.AddSublayer(CapaImagen); //Se agrega a la vista la nueva capa var Actualiza = CapaImagen.Frame; //se obtienen los frames de la capa imagen, para obtener las coordenadas Movimiento = new CMMotionManager(); //instancia nueva del movimiento. if (Movimiento.AccelerometerAvailable) //Validar si el dispositivo tiene el acelerometro esta disponible { //Si el aceleremetro esta disposnible le vamos a definir el intervalo para estar verificando los objectos que estan en el view controller Movimiento.AccelerometerUpdateInterval = 0.02; Movimiento.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, (data, error) =>//Metodo para detectar el movimiento del dispositivo. { //Se capturan las coordenadas de la capa imagen ActualizaX = CapaImagen.Frame.X; ActualizaY = CapaImagen.Frame.Y; if (ActualizaX + (nfloat)data.Acceleration.X * 10 > 0 && //Si el acelerometro se mueve ActualizaX + (nfloat)data.Acceleration.X * 10 < Altura - AnchoCapaa) //para que el objecto se mantega en la vista actual. { //Se actualiza la posicion. Actualiza.X = ActualizaX + (nfloat)data.Acceleration.X * 10; // el objeto empieza a tener movimiento } if (ActualizaY + (nfloat)data.Acceleration.Y * 10 > 0 && //Si el acelerometro se mueve ActualizaY + (nfloat)data.Acceleration.Y * 10 < Ancho - AlturaCapa) //para que el objecto se mantega en la vista actual. { //Se actualiza la posicion. Actualiza.Y = ActualizaY + (nfloat)data.Acceleration.Y * 10; // el objeto empieza a tener movimiento lblValueX.Text = data.Acceleration.X.ToString("00"); lblValueY.Text = data.Acceleration.Y.ToString("00"); lblValueZ.Text = data.Acceleration.Z.ToString("00"); //Se realiza la actualizaciòn de la capa imagen CapaImagen.Frame = Actualiza; //la variable tiene los valores en X y Z } } ); } } else { // System.Threading.Thread.CurrentThread.Abort();//Salga de la venta, la coloque en segundo plano y coloque la App en primer plano Console.WriteLine("N0rf3n - ViewDidLoad - Else"); Thread.CurrentThread.Abort(); } Console.WriteLine("N0rf3n - ViewDidLoad - End"); } catch (Exception ex) { Console.WriteLine("N0rf3n - ViewDidLoad - End/Catch Error : " + ex.Message); var alerta = UIAlertController.Create("Estado", ex.Message, UIAlertControllerStyle.Alert); alerta.AddAction(UIAlertAction.Create("Aceptar", UIAlertActionStyle.Default, null)); PresentViewController(alerta, true, null); } }
public override async void ViewDidLoad() { base.ViewDidLoad(); // Perform any additional setup after loading the view, typically from a nib. try { var verifica = new LAContext(); var autoriza = await verifica.EvaluatePolicyAsync (LAPolicy. DeviceOwnerAuthenticationWithBiometrics, "Autotenticacion Biometrica"); if (autoriza.Item1) { Altura = View.Bounds.Width; Ancho = View.Bounds.Height; AnchoCapa = Altura / 2; AlturaCapa = Ancho / 6; CapaImagen = new CALayer(); CapaImagen.Bounds = new CGRect(Altura / 2 - AnchoCapa / 2, Ancho / 2 - AlturaCapa / 2, AnchoCapa, AlturaCapa); CapaImagen.Position = new CGPoint(100, 100); CapaImagen.Contents = UIImage.FromFile("BolaCristal.jpg").CGImage; View.Layer.AddSublayer(CapaImagen); var actualiza = CapaImagen.Frame; Movimiento = new CMMotionManager(); if (Movimiento.AccelerometerAvailable) { Movimiento.AccelerometerUpdateInterval = 0.02; Movimiento.StartAccelerometerUpdates(NSOperationQueue.CurrentQueue, (data, error) => { ActualizaX = CapaImagen.Frame.X; ActualizaY = CapaImagen.Frame.Y; if (ActualizaX + (nfloat)data.Acceleration.X * 10 > 0 && ActualizaX + (nfloat)data.Acceleration.X * 10 < Altura - AnchoCapa) { actualiza.X = ActualizaX + (nfloat) data.Acceleration.X * 10; } if (ActualizaY + (nfloat)data.Acceleration.Y * 10 > 0 && ActualizaY + (nfloat)data.Acceleration.Y * 10 < Ancho - AlturaCapa) { actualiza.Y = ActualizaY + (nfloat) data.Acceleration.X * 10; } LblX.Text = data.Acceleration.X.ToString("0.0"); LblY.Text = data.Acceleration.Y.ToString("0.0"); LblZ.Text = data.Acceleration.Z.ToString("0.0"); CapaImagen.Frame = actualiza; }); } } else { System.Threading.Thread.CurrentThread.Abort(); } }catch (Exception ex) { Alerta = UIAlertController.Create("Status", ex.Message, UIAlertControllerStyle.Alert); Alerta.AddAction(UIAlertAction.Create("Aceptar", UIAlertActionStyle.Default, null)); PresentViewController(Alerta, true, null); } }
public override async void ViewDidLoad() { base.ViewDidLoad(); var verifica = new LAContext(); var autoriza = await verifica.EvaluatePolicyAsync (LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "Autenticación FaceID"); if (autoriza.Item1) { var voz = new AVSpeechUtterance("Está usted autorizado en la Aplicación, sea Bienvenido"); voz.Voice = AVSpeechSynthesisVoice.FromLanguage("es-MX"); habla.SpeakUtterance(voz); lblEstatus.Text = "Autorizado"; } else { lblEstatus.Text = "No Autorizado"; var Gravedad = new UIGravityBehavior(Imagen, btnConfirmar, btnGuardar, lblEstatus); var Colision = new UICollisionBehavior(Imagen, btnConfirmar, btnGuardar, lblEstatus) { TranslatesReferenceBoundsIntoBoundary = false }; var Rebote = new UIDynamicItemBehavior(btnConfirmar) { Elasticity = 1f }; Animador = new UIDynamicAnimator(View); Animador.AddBehaviors(Gravedad, Colision, Rebote); System.Threading.Thread.CurrentThread.Abort(); } var Firma = new SignaturePadView(View.Frame) { StrokeWidth = 3f, StrokeColor = UIColor.Black, BackgroundColor = UIColor.White, }; Firma.Frame = new CGRect(10, 500, 350, 200); Firma.Layer.BorderWidth = 1f; Firma.SignaturePrompt.TextColor = UIColor.Blue; Firma.Caption.TextColor = UIColor.White; Firma.Caption.Text = "Firmar en esta zona"; View.AddSubview(Firma); btnConfirmar.TouchUpInside += delegate { Imagen.Image = Firma.GetImage(); }; btnGuardar.TouchUpInside += delegate { var imagenfirma = Firma.GetImage(); try { imagenfirma.SaveToPhotosAlbum(delegate (UIImage imagen, NSError error) { }); lblEstatus.Text = "Guardado en biblioteca"; } catch (Exception ex) { lblEstatus.Text = ex.Message; } }; }