MasterKale / SimpleWebAuthn

WebAuthn, Simplified. A collection of TypeScript-first libraries for simpler WebAuthn integration. Supports modern browsers, Node, Deno, and more.
https://simplewebauthn.dev
MIT License
1.61k stars 137 forks source link

"No available authenticator recognized any of the allowed credentials" in iOS, even in example app #207

Closed cannikin closed 2 years ago

cannikin commented 2 years ago

Got my implementation working beautifully in Chrome and Safari on the desktop, no problems.

Moving to iOS (15.5), registration works, but when I go to authenticate I get No available authenticator recognized any of the allowed credentials my catch block around the startAuthentication() function. I thought maybe something about my specific implementation was messed up so I tried in the example app and I see the same thing:

Anyone else seen this?

lmarschall commented 2 years ago

What kind of authenticators are you using on desktop and on iOS? Maybe it‘s got something to do with the allowCredentials flag on the server side?

cannikin commented 2 years ago

On the desktop I have the authenticatorAttachment set to platform which means TouchID on my Macbook. Doing the same thing for my iPhone 13 means FaceID.

MasterKale commented 2 years ago

I think I know what's going on: Safari typically allows websites a single "freebie" indirect execution of WebAuthn. If there was any kind of asynchronicity before your call to one of the navigator.credentials then Safari would fail the API call right away with an inscrutable error message.

Fortunately sometime back in February Apple eased up on that, and now websites were more free to make API requests and perform other actions before ultimately calling WebAuthn, but only once for a given page load. After that you'd potentially have to reload the page to get WebAuthn to reliably trigger again.

I tested my example site on iOS too and no matter which button I clicked first, the first button would act as expected, while the second button would always error out in the same way you described. This is making me believe that you're describing that Safari limitation.

cannikin commented 2 years ago

Hmm, is there any workaround for that, then? This is in React, so there's potentially an infinite number of events before any WebAuthn invocation! startAuthentication() itself is async and wraps the calls to navigator, what are we supposed to do if you need to call navigator directly in an onClick?