Saturday, September 27, 2014

Authenticate with TouchID



Last blog, you saw how to store sensitive data in keychain and how to trigger touchID authentication when accessing them. In this post, you'll see how to use TouchID API for local authentication. No Keychain here.

I've used this KeychainWrapper in a small app KeychainTouchIDTest hosted on github very much inspired by the one used on session 711 of WWDC 2014. but this one is written in Swift ;)

Passcode Set

TouchId is used in complement to passcode feature. If you want to use it you will need to have your passcode set in your iOS8 settings.

LocalAuthentication and TouchID

In your AppDelegate.swift class, define promptTouchId method:
    func promptTouchID() {
        var myContext = LAContext()
        var authError: NSError? = nil
        var myLocalizedReasonString:String = "Authenticate using your finger"
        if (myContext.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, error:&authError)) {   // [1]
            
            myContext.evaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics,         // [2]
                localizedReason: myLocalizedReasonString,                              // [3]
                reply: {(success: Bool, error: NSError!)->() in
                    
                    if (success) {
                        println("User authenticated")
                    } else {
                        switch (error.code) {
                        case LAError.AuthenticationFailed.toRaw():
                            println("Authentication Failed")
                            
                        case LAError.UserCancel.toRaw():
                            println("User pressed Cancel button")
                            
                        case LAError.UserFallback.toRaw():                               // [4]
                            println("User pressed \"Enter Password\"")
                            
                        default:
                            
                            println("Touch ID is not configured")
                        }
                        
                    println("Authentication Fails");
                    let alert = UIAlertView(title: "Error", message: "Auth fails!", delegate: nil, cancelButtonTitle:"OK")
                    alert.show()
                }
            })
        } else {
            println("Can not evaluate Touch ID");
            let alert = UIAlertView(title: "Error", message: "Your passcode should be set!", delegate: nil, cancelButtonTitle:"OK")
            alert.show()
        }
    }
In [1], you first check wether passcode is set and touchId feature is available on this device.

In [2], you call the authentication process. DeviceOwnerAuthenticationWithBiometrics is an enum which (for now) contains only one value. But future will open room for other means of authentication, let's keep an eye on WWDC next sessions.

You can add an additional string in [3] which describes why you are doing this operation. You should always inform the user why he is prompted for Touch ID authentication.

Allow a user fallback in [4]. Your user might want to authenticate by other means than finger recognition. You will have to implement your own password strategy, passcode fallback is not yet available on programmable API.

To prompt at start-up, call promptTouchID method from application:didFinishLaunchingWithOptions: in AppDelegate:
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        promptTouchID()
        return true
    }
I hope this serie of three posts: helped you get a view on what's new on TouchID and Keychain APIs on iOS8. Feel free to share your experience with it, I'd love to hear it.

Happy iOS8!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.