Биометрическая аутентификация iOS: Попробуйте пароль работать только после второй попытки биометрического сбоя - PullRequest
0 голосов
/ 31 мая 2019

Я впервые пробую биометрическую аутентификацию на iOS.

Мой код аутентификации touch id работает отлично.Но если сенсорный идентификатор не удается, я хочу аутентифицироваться с помощью PIN-кода устройства.Но это работает только после второй попытки идентификатора прикосновения.В первый раз, когда это не удается, появляется предупреждение с кнопкой «Попробуйте пароль».Но при прикосновении к нему вместо того, чтобы идти к экрану для ввода пин-кода устройства, на нем снова отображается предупреждение ввода идентификатора касания.

Теперь, если снова не удается идентифицировать касание и если я нажимаю кнопку ввода пароля.На экран выводится PIN-код устройства.

Но почему он не работает с первого раза?Из документов Apple:

Кнопка отката изначально скрыта.Для Face ID после первой неудачной попытки аутентификации пользователю будет предложено повторить Face ID или отменить.Кнопка возврата отображается после второй неудачной попытки идентификации лица. Для Touch ID кнопка отката отображается после первой неудачной попытки Touch ID.

Я вижу, что она работает с такими приложениями, как Google Pay.Что я здесь делаю не так.

Вот мой код.

public partial class AuthenticationViewController : UIViewController
{

    private LAContext context;

    public AuthenticationViewController(IntPtr handle) : base(handle)
    {
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        if (UserDefaultsManager.RememberMe)
            TryAuthenticate();
        else
            AppDelegate.Instance.GotoLoginController();
    }

    private void TryAuthenticate()
    {
        context = new LAContext();
        NSError error = null;

        if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0) &&
            context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out error)) {
            // Biometry is available on the device
            context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics,
                "Unlock SmartFHR", HandleLAContextReplyHandler);
        } else {
            // Biometry is not available on the device
            if (error != null) {
                HandleLAContextReplyHandler(false, error);
            } else {
                TryDevicePinAuthentication(error);
            }
        }
    }

    private void TryDevicePinAuthentication(NSError error)
    {
        if (context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, out error)) {
            context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthentication,
                "Unlock SmartFHR", HandleLAContextReplyHandler);
        }
    }

    private void HandleLAContextReplyHandler(bool success, NSError error)
    {
        DispatchQueue.MainQueue.DispatchAsync(() => {
            if (success) {
                ContinueAfterAuthSuccess();
                return;
            }
            switch (error.Code) {
                case (long)LAStatus.UserCancel:
                    AppDelegate.Instance.GotoLoginController(true);
                    break;
                case (long)LAStatus.UserFallback:
                case (long)LAStatus.BiometryNotEnrolled:
                case (long)LAStatus.BiometryNotAvailable:
                    TryDevicePinAuthentication(error);
                    break;
            }
        });
    }

    private void ContinueAfterAuthSuccess()
    {
        if (Storyboard.InstantiateViewController("SplashController") is SplashController vc)
            AppDelegate.Instance.Window.RootViewController = vc;
    }

}

Когда попытка первого касания не удалась, и я нажимаю кнопку «Попробовать пароль», я вижу, что она вызывает HandleLAContextReplyHandler с кодом ошибкиLAStatus.UserFallback.

1 Ответ

1 голос
/ 03 июня 2019

Документация для LAPolicyDeviceOwnerAuthentication гласит:

Если Touch ID или Face ID доступны, зарегистрированы и не отключены, пользователя просят об этом первым.

Поэтому, когда вы использовали TryDevicePinAuthentication для отображения окна аутентификации, оно все равно сначала будет отображать биометрическое окно.

Если вы хотите, чтобы пользователь ввел пароль для прохождения аутентификации, я думаю, что достаточно DeviceOwnerAuthentication.

private void TryAuthenticate()
{
    context = new LAContext();

    // if Biometry is available on the device, it will show it first
    context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthentication, "Unlock SmartFHR", HandleLAContextReplyHandler);
}

Таким образом, вам нужно справиться только с ситуацией, когда пользователь отменяет эту аутентификацию. Потому что он автоматически отобразит окно ввода пароля при нажатии пользователем кнопки отката:

private void HandleLAContextReplyHandler(bool success, NSError error)
{
    DispatchQueue.MainQueue.DispatchAsync(() => {
        if (success)
        {
            ContinueAfterAuthSuccess();
            return;
        }
        switch (error.Code)
        {
            case (long)LAStatus.UserCancel:
                AppDelegate.Instance.GotoLoginController(true);
                break;
            default:
                break;
        }
    });
}
...