Software Development

Integrating Touch ID using the Local Authentication APIs in the iOS 8 SDK

Developers everywhere have wanted Touch ID access in iOS since the handy biometric fingerprint reader was introduced. With iOS 8, we finally got a way to do it.

Touch ID is the fingerprint reader that makes logging into iOS and purchasing iTunes Store content much easier, but it has a ton of possibilities. Fortunately, Apple has given developers the ability to integrate Touch ID into their apps using the Local Authentication API in the iOS 8 SDK. In this tutorial, we'll show you how to use Local Authentication to provide your own login system that prompts the user to sign in with their fingerprint.

The nitty-gritty of Touch ID

Touch ID is a biometric fingerprint reader that takes the place of the traditional Home button on iPhone 5s devices. It's purpose in iOS 7 is to unlock the device by scanning fingerprints, as well as authorize iTunes purchases, all without typing in a manual passcode.

All fingerprint data is stored securely in a part of the A7 processor called the "Secure Enclave," and no fingerprint data is available to apps, or even iOS itself. It secures all of this data, even if the OS or kernel were to become compromised.

The Secure Enclave is responsible for all cryptography processing tasks in iOS, and also handles device secrets, passcode secrets, and all Touch ID aspects (including locking down Touch ID when it detects potentially compromising security events).

A security event is any of the following items:

  • User repeatedly scans unrecognized finger, or an unauthorized user scan a finger
  • When device restarts
  • Several days of inactivity and non-use of Touch ID
  • Device has been remotely locked

In all of the scenarios above, the Touch ID sensor will be locked out, and a manual password must be entered in order to re-enable Touch ID.

Using Touch ID as an authentication mechanism

There are two ways to use Touch ID as an authentication mechanism in your iOS 8 applications. Let's take a look at the two ways.

Touch ID through Local Authentication

The Local Authentication APIs in iOS 8 is an API that returns a BOOL value for the success or failure of a finger scan. If there was an error, then an error code that gets returned will tell you what happened.

There are some caveats with using Local Authentication:

  • Application must be in the foreground (this doesn't work with backgrounded processes)
  • If you're using the straight Local Authentication method, you will be responsible for handling all errors and properly responding with your UI/UX to ensure there is an alternative method for logging into your apps.

If you already have a login system in place that doesn't utilize Keychain Access, then this might be the best option for it's ease of implementation and straightforwardness.

Touch ID through Keychain Access

If you utilize Keychain Access in your apps, then you'll be happy to hear that Keychain Access includes new Touch ID integration in iOS 8. Using the same Local Authentication APIs, Keychain Access automatically handles backup passcode implementations using the device user's passcode so you don't have to worry about implementation details.

Certain Keychain Items can be chosen to use Touch ID to unlock the item when requested in code through the use of the new Access Control Lists (ACLs) feature in iOS 8 Keychain. If the Touch ID has been locked out, then it will prompt the user to enter the device passcode to proceed without any application interruption.

There are a few caveats here, however, that may keep Keychain Access from being the best option for you, though:

  • Keychain items using the Touch ID attribute to unlock them will not be synced through iCloud Keychain
  • If you specify overly-broad Keychain item queries, then it can make multiple Touch ID dialogs appear, causing confusion for the user, meaning that you may have to re-write some Keychain queries to be more specific.

Integrating Local Authentication

localauthenticationfigurea.png
Using the Local Authentication API gives you the standard Touch ID UI in your apps.

In this how to, we want to focus on using the straight Local Authentication method, since we think that it'll be the most popular choice among developers who already implement an authentication system in their apps.

To set things up, we need to create an LAContext object that will handle the task of asking the user to authenticate using Touch ID.

LAContext *localAuthenticationContext = [[LAContext alloc] init];
__autoreleasing NSError *authenticationError; 
NSString *localizedReasonString = NSLocalizedString(@"Authenticate and log into your account.", @"String to prompt the user why we're using Touch ID.");

Above, we created the LAContext object, created a nil autoreleased NSError object that will be passed by reference to the -canEvaluatePolicy:error: method below to determine if an error occurred.

Next, we create the all-important localized reason string. All Touch ID operations require this string (and it should be localized in each language that your app supports). This string tells the user why you're requesting their fingerprint. If you pass an empty or nil string to the -evaluatePolicy:localizedReason:reply: method below, then you will get an error.

([localAuthenticationContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authenticationError]) {
    [localAuthenticationContext     
                evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                localizedReason:localizedReasonString
                reply:^(BOOL success, NSError *error) {
            if (success) {
                //Touch ID was a success, process login
            } else {
                //Touch ID failed, check the code property on the error object 
            }
    }]; 
} else {
    //Error using Touch ID -- most likely not a TouchID supported device
}

Above, we check to see if the device can use Touch ID by calling the -canEvaluatePolicy:error: method. If we get a YES back here, then we call -evaluatePolicy:localizedReason:reply: on the LAContext object, passing in our localized reason string. What we get back in the reply block is a BOOL and an NSError object. The BOOL will determine the success of the finger scan. If the BOOL is YES, then you can be assured that a registered fingerprint was scanned and that you can now process the login flow for the user. If you get a NO, then you'll want to check the code property on the error object to find out what went wrong.

As soon as you call -evaluatePolicy:localizedReason:reply:, you'll see the Touch ID alert view, prompting the user to scan their fingerprint (Figure A).

Some possible error codes that you should check for and implement UI/UX flows for are:

  • kLAErrorAuthenticationFailed
    • This happens whenever the finger scan was unsuccessful (the wrong finger scanned, etc.)
  • kLAErrorUserFallback
    • If Touch ID is locked, or if too many unsuccessful scans, then you should use the fallback flow and prompt the user to manually authenticate
    • Can also happen the user taps the "Enter Password" button in the Touch ID alert view.
  • kLAErrorUserCancel
    • Happens when the user taps the "Cancel" button in the Touch ID alert view.

What's next

Before using any of the Local Authentication APIs, we highly recommend taking a look at the WWDC session 711 from WWDC '14. It contains all the information you need to know about Touch ID and how to get started with both the Keychain Access implementation and the straight Local Authentication method, as well as some helpful tips on how to handle edge cases.

Have you began working on implementing Touch ID inside of your applications? If so, which method did you choose to use (straight Local Authentication vs. Keychain Access). Have any tips or tricks for other developers? Join in the discussion section below.

About

Cory Bohon is an indie developer specializing in iOS and OS X development. He runs a software company called Cocoa App and is also a developer at MartianCraft. He was introduced to technology at an early age and has been writing about his favorite te...

0 comments

Editor's Picks