Bagikan melalui


Menggunakan Touch ID dan Face ID dengan Xamarin.iOS

iOS mendukung dua sistem autentikasi biometrik:

  1. Touch ID menggunakan sensor sidik jari di bawah tombol Beranda.
  2. FACE ID menggunakan sensor kamera depan untuk mengautentikasi pengguna dengan pemindaian wajah.

Touch ID diperkenalkan di iOS 7 dan Face ID di iOS 11.

Sistem autentikasi ini mengandalkan prosesor keamanan berbasis perangkat keras yang disebut Enklave Aman. Enklave Aman bertanggung jawab untuk mengenkripsi representasi matematika data wajah dan sidik jari, dan mengautentikasi pengguna menggunakan informasi ini. Menurut Apple, data wajah dan sidik jari tidak meninggalkan perangkat dan tidak dicadangkan ke iCloud. Aplikasi berinteraksi dengan Enklave Aman melalui API Autentikasi Lokal dan tidak dapat mengambil data wajah atau sidik jari atau langsung mengakses Enklave Aman.

Touch ID dan Face ID dapat digunakan oleh aplikasi untuk mengautentikasi pengguna sebelum menyediakan akses ke konten yang dilindungi.

Konteks autentikasi lokal

Autentikasi biometrik pada iOS bergantung pada objek konteks autentikasi lokal, yang merupakan instans LAContext kelas. Kelas ini LAContext memungkinkan Anda untuk:

  • Periksa ketersediaan perangkat keras biometrik.
  • Mengevaluasi kebijakan autentikasi.
  • Mengevaluasi kontrol akses.
  • Sesuaikan dan tampilkan perintah autentikasi.
  • Gunakan kembali atau batalkan status autentikasi.
  • Mengelola kredensial.

Mendeteksi metode autentikasi yang tersedia

Proyek sampel mencakup yang AuthenticationView didukung oleh AuthenticationViewController. Kelas ini mengambil alih ViewWillAppear metode untuk mendeteksi metode autentikasi yang tersedia:

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);
    }
}

Metode ViewWillAppear ini dipanggil ketika UI akan ditampilkan kepada pengguna. Metode ini mendefinisikan instans LAContextCanEvaluatePolicy baru dan menggunakan metode untuk menentukan apakah autentikasi biometrik diaktifkan. Jika demikian, ia memeriksa versi sistem dan BiometryType enum untuk menentukan opsi biometrik mana yang tersedia.

Jika autentikasi biometrik tidak diaktifkan, aplikasi mencoba kembali ke autentikasi PIN. Jika autentikasi biometrik atau PIN tidak tersedia, pemilik perangkat belum mengaktifkan fitur dan konten keamanan tidak dapat diamankan melalui autentikasi lokal.

Mengautentikasi pengguna

AuthenticationViewController Dalam proyek sampel mencakup AuthenticateMe metode, yang bertanggung jawab untuk mengautentikasi pengguna:

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);
        }
    }
}

Metode AuthenticateMe ini dipanggil sebagai respons terhadap pengguna yang mengetuk tombol Masuk . Objek baru LAContext dibuat dan versi perangkat dicentang untuk menentukan properti mana yang akan diatur pada konteks autentikasi lokal.

Metode CanEvaluatePolicy ini dipanggil untuk memeriksa apakah autentikasi biometrik diaktifkan, kembali ke autentikasi PIN jika memungkinkan, dan akhirnya menawarkan mode yang tidak aman jika tidak ada autentikasi yang tersedia. Jika metode autentikasi tersedia, EvaluatePolicy metode digunakan untuk menampilkan UI dan menyelesaikan proses autentikasi.

Proyek sampel berisi data tiruan dan tampilan untuk menampilkan data jika autentikasi berhasil.