Open Vabs28 opened 6 years ago
I’m really not sure. https://youtu.be/fpaQpyU_QiM
Why do you want to cancel? What is the use case?
e.g. We prompt the user to authenticate using TouchID as soon as the app is opened. The app may also receive some authentication messages that he needs to action (select Accept/Reject on 2FA messages).
If the app receives an Authentication messages then we cancel the TouchID operation and show the authentication message.
I have rewritten some of the code so I'm now able to pass a LAContext to sign
and decrypt
. Sad thing is that I don't get to dismiss the LAContext once it is showing the fingerprint dialog. Do you know how?
Example
import UIKit
import LocalAuthentication
class ViewController: UIViewController {
var context: LAContext! = LAContext()
func createAccessControl(protection: CFString = kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, flags: SecAccessControlCreateFlags = [.userPresence, .privateKeyUsage]) -> SecAccessControl {
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, protection, flags, &error)
return accessControl!
}
override func viewDidLoad() {
super.viewDidLoad()
delay(1.0, queue: .main) {
self.decrypt()
}
}
func decrypt() {
let accessControl = createAccessControl()
context.evaluateAccessControl(accessControl, operation: .useKeySign, localizedReason: "Sign") { (success, error) in
DispatchQueue.main.async {
if success {
let alert = UIAlertController(title: "Authenticated", message: "Ready to sign/decrypt", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.show(alert, sender: nil)
} else {
let alert = UIAlertController(title: "Failed to authenticate", message: "Error: \(error!)", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.show(alert, sender: nil)
}
}
}
delay(3.0, queue: .main) {
self.context.invalidate()
}
}
}
func delay( _ delay: Double, queue: DispatchQueue, completion: @escaping () -> () ) {
queue.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)) { () -> Void in
completion()
}
}
It doesn't seem promising.
If you are able to remove the dialog then I'll be happy to finish the rewrite to support LAContext.
Hi I am new to Swift development. I also tried similar thing, it doesn't close TouchID dialog. Rather calling invalidate method doesn't do anything, you can still authenticate yourself with correct fingerprint.
So then I guess this is not possible... sadly. If you find a way to close it I’ll be more than happy to change the library
I have pushed my code to master. Whenever you sign or decrypt you will have the possibility of passing a LAContext.
Like this
let signature = try manager.sign(digest, authenticationContext: context)
In this archive you'll find two files and you'll see there's a bug with LAContext
Thanks a lot
Apple thinks this is fixed in latest GM. Are you, @Vabs28, able to check this?
It seems apple solved this when working with the LAContext directly. It doesn't work for me when the LAContext is presented by Security framework for some reason.
Hi
I am not sure if this is possible. Can we cancel TouchID authentication happening on decrypt operation if we dont want to proceed? LAContext has a method "invalidate" which invalidates LAContext and throws LAErrorAppCancel error.
e.g. We prompt user to authenticate using TouchID as soon as app is opened. We also make a background call to check if user is running on latest app. If user is running on old version then we cancel TouchID operation and show a message which says "Please update app to latest version."