The case where a person registers a new account (via credentials.create
) and subsequently logs in using the same browser (via credentials.get
) is straightforward, because at the time credentials.create
is called, the user must grant their browser permission to use Touch ID for a given domain. For example, see the image below, which is a modal prompting the user to allow Touch ID on the given domain, triggered by credentials.create
:
If you select "OK" in the modal shown above, you can complete registration with Touch ID. When you subsequently login to your account using the same browser, you see the modal depicted below, which offers a choice between authenticating with a security key and the previously-registered Touch ID. This modal is triggered by credentials.get
:
Here's the rub: If a user creates an account (credentials.create
) with Touch ID via another browser, for example Chrome, and then attempts to authenticate (credentials.get
) on Safari, Safari thinks they only have access to a security key, and does not provide Touch ID as an option. See below for reference:
Is this a known limitation of WebAuthn itself? It is common that people would use different browsers to access the same website, with the expectation that they can login on any browser, regardless of the one they used to create an account. Given that, it is troubling if WebAuthn does not support this behavior.
Most importantly - how are devs getting around this issue? Are you informing users that they are tied not only to the internal device that they originally registered to their account but also the browser they used? Are you calling credentials.create
immediately before credentials.get
? This seems like a hack but I am interested in any solutions.
Thanks very much in advance.
CodePudding user response:
Is this a known limitation of WebAuthn itself?
This has nothing to do with WebAuthn the API and everything to do with macOS. To date macOS is the one platform that requires WebAuthn credential management to take into account which browser the credential was registered in.
...how are devs getting around this issue?
One way to address this is to store the user's OS and browser at registration (via traditional user agent, the newer navigator.userAgentData, etc...) with the new credential. Then, at auth, grab the user's current OS and browser info and use it to filter credentials to include in allowCredentials
that you'll pass to navigator.credentials.get()
. If a credential was registered on macOS then filter by browser too; on other platforms you can simply filter by OS.
If allowCredentials
is empty on macOS after filtering the user's credentials (i.e. because the user has a single credential that was registered in Safari but the user is currently using Chrome) you need to handle that and prompt the user to log in some other way before prompting them to register Touch ID in Chrome.
This is incredibly annoying to deal with, but it's the reality of WebAuthn on macOS. Fingers crossed Apple's passkeys (now in Tech Preview on Monterey) will offer a similar experience to iOS' OS-level credential store once it rolls out more widely...