Streaming is available in most browsers,
and in the Developer app.
-
Meet Face ID and Touch ID for the web
Face ID and Touch ID provide a frictionless experience when logging in — and now you can use them on your websites in Safari with the Web Authentication API. Discover how to add this convenient and secure login alternative to your website.
Resources
Related Videos
WWDC20
-
Download
Hello and welcome to WWDC.
Hello everyone. I'm Jiewen from the WebKit Team. Today I'm going to talk about Face ID and Touch ID for the Web. This session is tailored for Web developers looking to add this cool new feature to their websites. Let's get started. There's a user experience in a few apps on my phone that I really like, which is the experience of using Face ID or Touch ID for re-signing into an app. Let me show you with my favorite demo application, Shiny. Shiny is an app that you can use every day, and it shows you a picture of something nice.
The first time I sign in to Shiny, I will need to enter my user name and password, and since I care deeply about security, I have enabled two-factor authentication for Shiny. In this case, I need to wait for an SMS second-factor code to continue.
And once I've submitted the SMS 2FA code, I'm signed in, and I can see this adorable dog. iOS makes signing in a better process with AutoFill, but even then, there are several steps and a lot of thinking for me to do. Shiny has a policy of wanting me to re-sign in after being inactive for a few hours. You will see a policy like that in lots of high-security contexts, like signing into a bank. But this time, when I sign in, rather than go through a password and SMS 2FA flow, instead I just Face ID, like that. Boom. I'm signed in. It is both much faster and more secure.
This session is about bringing the same user experience to your website. Here is a quick overview. I click the "sign in" button, Safari prompts me for confirmation, then, boom, Face ID, I'm signed in. Now, let's dive into how to add this to your website. Face ID and Touch ID on the Web is powered by a standard called Web Authentication. I'll start by talking a little about that standard, then Apple's implementation of what's called a platform authenticator.
Next, I'll cover the basics of what it takes to adopt this awesome new feature. Finally, end on some important best practices.
Now, let's talk about the Web Authentication standard. Web Authentication is a JavaScript API to allow you, Web developers, to use public key-based authentication on the Web.
This API is built on top of public key cryptography and brings many unique features along with it.
Let's start with some high-level concepts.
First, you need to get used to this strange yet familiar concept called relying party, which essentially means your website.
Second, the API generates and makes use of a JavaScript object called public key credentials, which contains all the necessary information to perform your authentication.
Third, all private keys are managed by devices called authenticators instead of the user's directory. An authenticator could be a security key, which you might have heard about, or the iPhone we just saw. Web browsers manage the interface for users to interact with an authenticator and bridge the responses from the authenticator to the website.
Fourth, authenticators can, if necessary, prove their properties cryptographically via a process called attestation.
These concepts may be new to many of you, but this session should explain everything you need to know to get started using them on your websites. Let's take a look at why you want to do that.
First, Web Authentication provides strong authentication through public key cryptography, which is much stronger than passwords and can't be reused or breached.
But more importantly, it is phishing-resistant.
Safari will only allow public key credentials created by this API to be used within the website they were created, and the credentials can never be exported out from the authenticator they were created as well. This means that once a public key credential has been provisioned, there is no way for a user to accidentally divulge it to another party. Cool, right? This is the overview of Web Authentication standard. I will talk about the actual API later. Now let's talk about some unique features Apple does to enable Face ID and Touch ID under the Web Authentication standard.
An authenticator like the iPhone is called a platform authenticator, because the authenticator is a feature built into the platform. There are two important properties that Apple builds into the authenticator. The first one, as we saw, is the Face ID and Touch ID, which is used to verify users' identity.
The second one is Secure Enclave, which is a processor that manages all the private keys and guarantees that they cannot leave the device.
By combining both, each sign-in performed with the Face ID or Touch ID is essentially a multi-factor authentication. The response the device sends back to the websites encapsulates two factors: something you have, the iPhone, and something you are, the biometrics. And the sign-in only takes a single tap. This is amazing. However, websites like a bank could be regulated to enforce multi-factor authentication. Information stored in the response might not be sufficient. They want some extra proof from the manufacturer that the device really, really preserves those nice properties. You do this with an optional security feature called attestation.
Attestation is basically a secure way for you to ask a device manufacturer that the device is real and really has the capabilities it says it does. This is great for the specific-use cases like the one that I just mentioned.
However, it can be implemented in a way to violate user privacy. For example, a device can be instructed to use a single, unique attestation certificate.
Then the unique certificate becomes an easy tracking vector to link all of a user's attested accounts across the Web.
Apple cares about users' privacy. Therefore, Apple has built its own attestation service. It generates unique certificates for every credential, and therefore websites can no longer use them to track users. That is called Apple Anonymous Attestation, which is coming soon.
With this rich set of features, Apple's platform authenticator is truly amazing.
Now let's walk through how to adopt it in your website. There are three different methods your website will need to use. All of them are promise-based API. First, you should check if the current device supports this feature. You can do this by calling PublicKeyCredential.isUserVerifying- PlatformAuthenticatorAvailable.
Then, when getting a user set up to use it, you will need to call navigator.credentials.create to create a PublicKeyCredential object that contains the necessary authentication information.
Finally, when a user wants to sign in to your site, call navigator.credentials.get, which returns a credential object that you can verify on your server to authenticate the user.
These are the entry points to the Web Authentication API. Now let's take a look at how to use them to get Face ID and Touch ID on your website.
To do feature detection, it is super easy. Just call PublicKeyCredential.isUser- VerifyingPlatformAuthenticatorAvailable, which will simply return a Boolean to tell you whether or not the feature can be used.
Now it's time to onboard the user. To do that, you might need to first let your users sign in with their old-school password credential. Then you could show a notification to the user, saying, "Hey, we got this cool new feature to let you use Face ID or Touch ID to bypass the user name and password next time when you sign in. Would you like to enable that?" The notification could be a full Web page, a banner or a floating pop-up, depending on the style of your website. In this Shiny website that I built, I decided to use a full-page notification.
Here is the notification. Most users at this point will probably press "OK." Then you should prepare your website with the following script to enable Touch ID with Web Authentication API.
First things first, let's construct the options to pass to the method. It looks scary. However, after I break it down for you, you'll see that it's actually pretty easy. First, you need to tell the browser what website you are. Then, some information about the user. And then you get to specify what crypto you want to use. Now, good old-school challenge for our beloved crypto. And then tell the browser you want to use the platform authenticator. This is the key option here.
Finally, this is completely optional. Since Shiny has some special security requirements, it decides to opt in for attestation. You see? That's simple. Now, you pass these options to navigator.credentials.create, and then Safari will handle the UI and give you back a PublicKeyCredential. It's important to call this method within user-activated events, though.
Let's see a demo of how everything comes together.
First, let me sign in to Shiny with my primary credential. Then I get the notification. I mean, why not? Safari will then show a confirmation UI. Click "OK" and then Touch ID. I'm done. So that's the full user onboarding experience. Beautiful. But we are just halfway done. What you just saw is the front-end user experience. We still need to do something in the back end to process the response.
Let's take a look at an overview of the response.
To begin with, it contains an ID that you should save to refer to this particular credential in the future. Second, it contains a response that is for enrollment.
In that response, you'll get some metadata that is generated by the browser for you to validate. Then it is the meat of the response: an attestationObject that contains the public key data and attestation certificates.
If you didn't opt in for attestation, you will instead get back a "none" attestation statement as shown here. So that's the overview of the response.
Depending on your server's configuration, code could be very different. However, here is a checklist you should follow in this order. First, validate all metadata: the client data and the authenticator data. Second, if you opt in to attestation, you should validate the attestation statement.
Third, save the credential ID and the public key data, which you will use for future sign-in. Lastly, you can optionally set a server-side cookie to indicate Face ID or Touch ID is enabled for this particular account on this device.
This will make the re-authentication process a lot easier. So that's all you need to do for onboarding users. Now let's move to sign in.
If you have saved a cookie about the Touch ID-enabled account during enrollment, then now you could list it as a fast path for sign-in. To use Touch ID for your fast path, you will need the following script.
This is a very similar formula, like the enrollment, to do sign-in. The must-have field here is the challenge, just like any other public key crypto. Then it is helpful for you to tell Safari the exact credential you are planning to use, so that Safari can offer the most optimized UI for the user.
Most importantly, you need to specify the transports.
Now you pass these options to navigator.credentials.get, and then Safari will handle the UI and give you back a PublicKeyCredential, just like the enrollment.
Also, same as the enrollment, it's important to call this method within user-activated events.
Let's see a demo of how everything comes together.
Let me click the "sign in" button. Safari will then show a confirmation UI. Click "continue" and then Touch ID. I'm in. So that's just how easy it is to use Touch ID to sign in. Now let's focus on the back end.
In the sign-in case, the returned PublicKeyCredential is slightly different. The type of the response is now AuthenticatorAssertionResponse. The meat of the response here is the signature. Yes, the old-school signature you need to verify for every public key crypto. So that's the response.
The checklist here for sign-in is much simpler than the enrollment part. First, you need to validate that the user ID is indeed one of your users, and then check if the credential ID is associated with that user ID. Once you've done that, you then validate all other metadata. Finally, you verify the signature. Then you can log the user in, and you are done.
That is everything you need to do to enable Face ID and Touch ID on the Web. Let me recap those three things. First, you need to detect the existence of the feature. Then you should show a notification to ask users to enable the feature right after the user has signed in with traditional mechanisms. And then you are ready to go with Face ID or Touch ID for future sign-in.
Face ID and Touch ID for the Web is available in Safari as SFSafariViewController and ASWebAuthenticationSession in macOS, iPadOS and iOS.
Finally, some best practices.
The most important one is to use this feature as an alternative way to sign in, not the only one. Since the private key is tied to a device, if this is the only way to sign in to your website, your users will be forever locked out of their accounts if they lose their devices. Use feature detection instead of user-agent strings to detect this feature.
Call navigator.credentials.create and .get within user-activated events. If you ever need to set a flag to indicate if this feature is enabled for an account on a device, use a server-side, secure, HttpOnly cookie, which should give you the longest-term storage.
Finally, for websites that have already enabled security keys with Web Authentication, you should consider whether it makes sense to present this feature along with security keys to your users, because the end-to-end user experiences are quite different.
In summary, today I introduced Face ID and Touch ID for the Web, which provides a frictionless user experience and yet a strong multi-factor authentication mechanism. It can be easily integrated into your website to streamline your user's sign-in experience without having to change the way you manage your user session state.
Please start testing this feature today and file any potential bugs on Feedback Assistant or bugs.webkit.org. Thanks for watching.
-
-
7:44 - Feature detection
// Feature detection const isAvailable = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable(); if (isAvailable) { // Continue to enrollment or sign in // ... }
-
8:42 - Enrollment
// Enrollment const options = { publicKey: { rp: { name: "example.com" }, user: { name: "[email protected]", id: userIdBuffer, displayName: "John Appleseed" }, pubKeyCredParams: [ { type: "public-key", alg: -7 } ], challenge: challengeBuffer, authenticatorSelection: { authenticatorAttachment: "platform" }, attestation: "direct" } }; const publicKeyCredential = await navigator.credentials.create(options);
-
11:42 - Sign in
// Sign in const options = { publicKey: { challenge: challengeBuffer, allowCredentials: [{ type: "public-key", id: credentialIdBuffer, transports: ["internal"] }] } }; const publicKeyCredential = await navigator.credentials.get(options);
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.