Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for optional authenticator_attachment in PublicKeyCredential #370

Conversation

8ma10s
Copy link
Contributor

@8ma10s 8ma10s commented Sep 16, 2022

Why

https://w3c.github.io/webauthn/#iface-pkcredential

Level 3 draft of WebAuthn adds an optional parameter authenticatorAttachment on PublicKeyCredential (and AuthenticatorAttestationResponse and AuthenticatorAssertionResponse which inherits it, of course).

This field allows RP developers to detect whether the authentication was done using platform authenticator that always exists on that particular device, or cross-platform authenticator that only exists on that device temporarily.

In the latter case of using cross-platform authenticator, RP can prompt the user to register a platform authenticator so that the user won't lose the ability to sign in on that device.

Note: If, as the result of a registration or authentication ceremony, authenticatorAttachment's value is "cross-platform" and concurrently isUserVerifyingPlatformAuthenticatorAvailable returns true, then the user employed a roaming authenticator for this ceremony while there is an available platform authenticator. Thus the Relying Party has the opportunity to prompt the user to register the available platform authenticator, which may enable more streamlined user experience flows.

Since some vendors (I confirmed with Mac chrome) are already passing this optional parameter authenticatorAttachment, I want this gem to be able to support reading values from that field.

What

Allow initializing PublicKeyCredential class with an optional argument authenticator_attachment

Misc

I obtained the authenticator response returned from the client on sign-in (using dev-console), and ran WebAuthn::Credential.from_get on that response.
As you can see, I can now obtain the value of authenticator_attachment

image

@halo
Copy link

halo commented Oct 8, 2022

UPDATE

Never mind me! I forgot that the authenticatior_selection contains theauthenticator_attachment attribute. See this test

Older Post

Hi!

Can we also add this to WebAuthn::PublicKeyCredential::CreationOptions? It's helpful to read that value, but it would be even better to also set that value.

Because, I noticed that Safari on macOS behaves differently than Safari on iOS, depending on what you specify in authenticator_attachment. You can check it yourself for example here: demo.quado.io

If you use Authenticator type: Unspecified, no authenticator_attachment is sent to the browser, and Safari on macOS will not allow a platform authenticator:

Screen Shot 2022-10-08 at 11 12 23

But if you choose Authenticator type: Platform, then authenticator_attachment: platform is sent to the browser, and Safari on macOS will allow using Touch ID:

Screen Shot 2022-10-08 at 11 12 34

Safari on iOS will provide Touch ID Passkey, even without sending authenticator_attachment.

Maybe we should have a separate PR for the creation options?

PS: I didn't know about PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable where you can simply check via JS in the browser whether a platform authenticator is available or not. So you can even decide upfront whether to ask for "platform" or not. Unfortunately, if you choose platform, Safari will not allow a portable USB key 🫣

Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ssym0614! Thank you so much for opening this!

I'm not being able to get the authenticator_attachment parameter using the demo app in my Mac with both Chrome and Safari – are you still able to get it?. Code looks good though!

It feels to me that it could be a good idea to add this argument to the initialization of PublicKeyCredential in both spec/webauthn/public_key_credential_with_attestation_spec.rb and spec/webauthn/public_key_credential_with_assertion_spec.rb – more as documentation that anything, really.

@8ma10s
Copy link
Contributor Author

8ma10s commented Dec 14, 2022

Let me check. (sorry for the late reply)

@8ma10s
Copy link
Contributor Author

8ma10s commented Feb 6, 2023

@santiagorodriguez96
sorry for late response.

I just played around with the demo rails server, and it seems like the problem is as follows:

So basically, it's not the rails gem's problem, but the frontend code's problem.
I confirmed that switching the frontend implementation from using https://github.com/ericelliott/credential to https://github.com/github/webauthn-json successfully returns authenticatorAttachment to your backend demo code.

Here's what I got for the backend after the modification:

    webauthn_credential = WebAuthn::Credential.from_get(params)
    Rails.logger.info(webauthn_credential)

produces

{"type"=>"public-key", "id"=>"TecfTRasmz5e6BkT6T8Yz4cZYDUW_NLXInHrjMojI3A", "rawId"=>"TecfTRasmz5e6BkT6T8Yz4cZYDUW_NLXInHrjMojI3A", "authenticatorAttachment"=>"platform", "response"=>{
...

It feels to me that it could be a good idea to add this argument to the initialization of PublicKeyCredential in both spec/webauthn/public_key_credential_with_attestation_spec.rb and spec/webauthn/public_key_credential_with_assertion_spec.rb

added 👍
3e17fcd

I also found this thing called fake_client that's used in some of the specs, so I modified that code too.
This ensures that "even if frontend code (and thus backend server using this gem) starts passing in authenticatorAttachment, the existing behavior will not get affected.

Copy link
Contributor

@santiagorodriguez96 santiagorodriguez96 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@santiagorodriguez96 sorry for late response.

I just played around with the demo rails server, and it seems like the problem is as follows:

So basically, it's not the rails gem's problem, but the frontend code's problem. I confirmed that switching the frontend implementation from using https://github.com/ericelliott/credential to https://github.com/github/webauthn-json successfully returns authenticatorAttachment to your backend demo code.

Here's what I got for the backend after the modification:

    webauthn_credential = WebAuthn::Credential.from_get(params)
    Rails.logger.info(webauthn_credential)

produces

{"type"=>"public-key", "id"=>"TecfTRasmz5e6BkT6T8Yz4cZYDUW_NLXInHrjMojI3A", "rawId"=>"TecfTRasmz5e6BkT6T8Yz4cZYDUW_NLXInHrjMojI3A", "authenticatorAttachment"=>"platform", "response"=>{
...

@8ma10s Good call! The problem actually was that we are using a really old version of WebAuthn-JSON (v.0.4.5). I can confirm that after upgrading the package to the last version (v2.1.1) the authenticatorAttachment parameter is received in the server.

I'll update the package on the demo to use the last version. Thank you for bringing that up!

Really sorry for the delayed response.

Code looks good! Thank you so much! 💯 🤩

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants