Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TouchID activateTouchWithResponse returns success without requesting fingerprint

Tags:

I have the following implementation of LocalAuthentication as described in many places.

context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
        dispatch_async(dispatch_get_main_queue(), {

        if success {
            let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        if let error = error {
            var message :String

            switch(error.code) {
            case LAError..AuthenticationFailed:
                message = "There was a problem verifying your identity."
            case LAError..UserCancel:
                message = "You pressed cancel."
            case LAError..UserFallback:
                message = "You pressed password."
            default:
                message = "Touch ID may not be configured"
            }

            let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
            self.presentViewController(alert, animated: true, completion: nil)
        }
    })
})

But after I've successfully authenticated with my fingerprint, then evaluatePolicy(, localizedReason:, reply:) returns success without requesting for any fingerprint. I'm actually enabling or disabling TouchID with a UISwitch, so after disabling and re enabling, I'd like to re-authenticate and re enter my fingerprint.

Why is it caching the authentication?

Thanks

like image 347
Cristian Pena Avatar asked Jul 14 '16 16:07

Cristian Pena


2 Answers

LAContext, once evaluated, will return success until it's deallocated. You can manually invalidate it and then the returned error will be LAError.InvalidContext.

If you want to be prompted with a TouchID confirmation every time, you need to create a LAContext every time. This could be achieved

context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "Logging in with Touch ID", reply: { (success : Bool, error : NSError? ) -> Void in
        dispatch_async(dispatch_get_main_queue(), {

        if success {
            let alert = UIAlertController(title: "Success", message: "", cancelButtonTitle: "Great!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        if let error = error {
            var message :String

            switch(error.code) {
            case LAError..AuthenticationFailed:
                message = "There was a problem verifying your identity."
            case LAError..UserCancel:
                message = "You pressed cancel."
            case LAError..UserFallback:
                message = "You pressed password."
            default:
                message = "Touch ID may not be configured"
            }

            let alert = UIAlertController(title: "Error", message: message, cancelButtonTitle: "Darn!")
            self.presentViewController(alert, animated: true, completion: nil)
        }

        context = LAContext()
    })
})
like image 55
Cristian Pena Avatar answered Sep 29 '22 19:09

Cristian Pena


Since ios 9 there is touchIDAuthenticationAllowableReuseDuration for the context

The duration for which Touch ID authentication reuse is allowable. If the device was successfully authenticated using Touch ID within the specified time interval, then authentication for the receiver succeeds automatically, without prompting the user for Touch ID. The default value is 0, meaning that Touch ID authentication cannot be reused. The maximum allowable duration for Touch ID authentication reuse is specified by the LATouchIDAuthenticationMaximumAllowableReuseDuration constant. You cannot specify a longer duration by setting this property to a value greater than this constant. Availability iOS (9.0 and later), macOS (10.12 and later)

if you set for example to 60

context.touchIDAuthenticationAllowableReuseDuration = 60

It will auto succeed without checking, if the user has successfully passed the touch id checking in the last 60 secs.

So, you can set to the value that suites you. I find it a good very good and it's annoying to ask the user to touch again while he just did it a few seconds ago.(to unlock the screen for example).

like image 33
Ismail Avatar answered Sep 29 '22 18:09

Ismail