Použití Touch ID a Face ID s Xamarin.iOS

Download Sample Stažení ukázky

iOS podporuje dva biometrické systémy ověřování:

  1. Touch ID používá snímač otisku prstu pod tlačítkem Domů.
  2. Face ID používá senzory přední kamery k ověřování uživatelů pomocí skenování obličeje.

Touch ID bylo zavedeno v iOS 7 a Face ID v iOS 11.

Tyto systémy ověřování spoléhají na hardwarový procesor zabezpečení označovaný jako Secure Enklave. Zabezpečená enkláva zodpovídá za šifrování matematických reprezentací dat tváře a otisku prstu a ověřování uživatelů pomocí těchto informací. Podle Apple data obličeje a otisku prstu neopustí zařízení a nejsou zálohované do iCloudu. Aplikace komunikují se zabezpečeným enklávem prostřednictvím místního rozhraní API pro ověřování a nemůžou načítat data tváře nebo otisku prstu ani přímo přistupovat k zabezpečené enklávě.

Touch ID a Face ID můžou aplikace používat k ověření uživatele před poskytnutím přístupu k chráněnému obsahu.

Místní kontext ověřování

Biometrické ověřování v iOSu závisí na místním objektu kontextu ověřování , což je instance LAContext třídy. Třída LAContext umožňuje:

  • Zkontrolujte dostupnost biometrického hardwaru.
  • Vyhodnocení zásad ověřování
  • Vyhodnocení řízení přístupu
  • Přizpůsobte a zobrazte výzvy k ověření.
  • Znovu použijte nebo zneplatnit stav ověřování.
  • Správa přihlašovacích údajů

Zjištění dostupných metod ověřování

Ukázkový projekt zahrnuje zálohovaný AuthenticationView objektem AuthenticationViewController. Tato třída přepíše metodu ViewWillAppear pro detekci dostupných metod ověřování:

partial class AuthenticationViewController: UIViewController
{
    // ...
    string BiometryType = "";

    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        unAuthenticatedLabel.Text = "";
    
        var context = new LAContext();
        var buttonText = "";

        // Is login with biometrics possible?
        if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out var authError1))
        {
            // has Touch ID or Face ID
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                context.LocalizedReason = "Authorize for access to secrets"; // iOS 11
                BiometryType = context.BiometryType == LABiometryType.TouchId ? "Touch ID" : "Face ID";
                buttonText = $"Login with {BiometryType}";
            }
            // No FaceID before iOS 11
            else
            {
                buttonText = $"Login with Touch ID";
            }
        }

        // Is pin login possible?
        else if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, out var authError2))
        {
            buttonText = $"Login"; // with device PIN
            BiometryType = "Device PIN";
        }

        // Local authentication not possible
        else
        {
            // Application might choose to implement a custom username/password
            buttonText = "Use unsecured";
            BiometryType = "none";
        }
        AuthenticateButton.SetTitle(buttonText, UIControlState.Normal);
    }
}

Metoda ViewWillAppear se volá, když se uživatelské rozhraní chystá zobrazit uživateli. Tato metoda definuje novou instanci LAContext a použije metodu CanEvaluatePolicy k určení, jestli je povolené biometrické ověřování. Pokud ano, zkontroluje systémovou verzi a BiometryType výčet, aby určil, které biometrické možnosti jsou k dispozici.

Pokud biometrické ověřování není povolené, aplikace se pokusí vrátit k ověřování PIN kódem. Pokud není k dispozici biometrické ani PIN ověřování, vlastník zařízení nepovolil funkce zabezpečení a obsah nelze zabezpečit prostřednictvím místního ověřování.

Ověření uživatele

Ukázkový AuthenticationViewController projekt obsahuje metodu AuthenticateMe , která je zodpovědná za ověřování uživatele:

partial class AuthenticationViewController: UIViewController
{
    // ...
    string BiometryType = "";

    partial void AuthenticateMe(UIButton sender)
    {
        var context = new LAContext();
        NSError AuthError;
        var localizedReason = new NSString("To access secrets");
    
        // Because LocalAuthentication APIs have been extended over time,
        // you must check iOS version before setting some properties
        context.LocalizedFallbackTitle = "Fallback";
    
        if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
        {
            context.LocalizedCancelTitle = "Cancel";
        }
        if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
        {
            context.LocalizedReason = "Authorize for access to secrets";
            BiometryType = context.BiometryType == LABiometryType.TouchId ? "TouchID" : "FaceID";
        }
    
        // Check if biometric authentication is possible
        if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out AuthError))
        {
            replyHandler = new LAContextReplyHandler((success, error) =>
            {
                // This affects UI and must be run on the main thread
                this.InvokeOnMainThread(() =>
                {
                    if (success)
                    {
                        PerformSegue("AuthenticationSegue", this);
                    }
                    else
                    {
                        unAuthenticatedLabel.Text = $"{BiometryType} Authentication Failed";
                    }
                });
    
            });
            context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason, replyHandler);
        }

        // Fall back to PIN authentication
        else if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, out AuthError))
        {
            replyHandler = new LAContextReplyHandler((success, error) =>
            {
                // This affects UI and must be run on the main thread
                this.InvokeOnMainThread(() =>
                {
                    if (success)
                    {
                        PerformSegue("AuthenticationSegue", this);
                    }
                    else
                    {
                        unAuthenticatedLabel.Text = "Device PIN Authentication Failed";
                        AuthenticateButton.Hidden = true;
                    }
                });
    
            });
            context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, localizedReason, replyHandler);
        }

        // User hasn't configured any authentication: show dialog with options
        else
        {
            unAuthenticatedLabel.Text = "No device auth configured";
            var okCancelAlertController = UIAlertController.Create("No authentication", "This device does't have authentication configured.", UIAlertControllerStyle.Alert);
            okCancelAlertController.AddAction(UIAlertAction.Create("Use unsecured", UIAlertActionStyle.Default, alert => PerformSegue("AuthenticationSegue", this)));
            okCancelAlertController.AddAction(UIAlertAction.Create("Cancel", UIAlertActionStyle.Cancel, alert => Console.WriteLine("Cancel was clicked")));
            PresentViewController(okCancelAlertController, true, null);
        }
    } 
}

Metoda AuthenticateMe se volá v reakci na uživatele klepnutím na tlačítko Přihlásit . Vytvoří se instance nového LAContext objektu a verze zařízení se zkontroluje a určí, které vlastnosti se mají nastavit v místním kontextu ověřování.

Volá se CanEvaluatePolicy metoda, která kontroluje, jestli je povolené biometrické ověřování, pokud je to možné, vraťte se k ověřování PIN kódem a nakonec nabídnout nezabezpečený režim, pokud není k dispozici žádné ověřování. Pokud je k dispozici metoda ověřování, EvaluatePolicy použije se metoda k zobrazení uživatelského rozhraní a dokončení procesu ověřování.

Ukázkový projekt obsahuje napodobená data a zobrazení pro zobrazení dat, pokud je ověření úspěšné.