首页 > 解决方案 > iOS 生物识别身份验证:仅在第二次生物识别失败尝试后尝试密码工作

问题描述

我是第一次在 iOS 上尝试生物特征认证。

我的 touch id 身份验证代码运行良好。但如果 touch id 失败,我想使用设备 PIN 进行身份验证。但这仅在第二次触摸 ID 尝试失败后才有效。第一次,当它失败时,会显示一个带有“尝试密码”按钮的警报。但是当触摸它时,它并没有进入屏幕输入设备引脚,而是再次显示输入触摸ID警报。

现在,如果触摸 ID 再次失败并且我触摸输入密码按钮。它将进入屏幕以输入设备 PIN。

但为什么它第一次不起作用?来自苹果文档:

后备按钮最初是隐藏的。对于 Face ID,在首次尝试验证失败后,将提示用户再次尝试 Face ID 或取消。在第二次失败的面容 ID 尝试后会显示后备按钮。对于 Touch ID,在第一次不成功的 Touch ID 尝试后会显示回退按钮。

我看到它可以与谷歌支付等应用程序一起使用。我在这里做错了什么。

这是我的代码。

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

}

当第一次触摸 id 尝试失败并且我触摸 Try Password 按钮时,我看到它调用了带有错误代码 LAStatus.UserFallback 的 HandleLAContextReplyHandler。

标签: iosxamarin.iosbiometricstouch-id

解决方案


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

推荐阅读