Reputation: 296
Preface
I am new to cybersecurity. I've always been hesitant to implement an authentication system into personal projects because I was scared by the security implications (mainly passwords and authenticating a user). However, I am very excited about WebAuthn and Apple's Passkeys because this standard promises to be safer and should mean less responsibility for me! However, I have had a nightmare of a time trying to setup what I thought should be a simple demo project. There just isn't enough information or examples to work off of.
Problem
I have created a simple .NET 6 Web API project and a simple Angular project. Here is the flow so far:
PublicKeyCredential
using the challenge and calling navigator.credentials.create(...);
The above works perfectly. The next step should be to send the new PublicKeyCredential
to the server so the server can store this credential for authentication later. The problem is that this PublicKeyCredential
uses ArrayBuffers
that cannot be serialized and sent to the server (at least not easily). Am I just doing this wrong? I just simply cannot find any solid and reliable way to get the PublicKeyCredential
back to the server.
What I have tried
ArrayBuffers
to strings and base64 strings as suggested here but this has not worked for me. When the credential gets to the server, I decode the byte[]
, and attempt to call _fido2.MakeNewCredentialAsync(...)
I get a weird error that says the "Attestation Object is invalid. Unhandled State. Was SimpleValue."Conclusion
If anyone has any examples of WebAuthn working in a very simple environment, I would love to take a look. Or if you have suggestions for me on my implementation that is also welcome!
Upvotes: 1
Views: 1470
Reputation: 296
While the answers to this question did ultimately help me get the PublicKeyCredential to the server (through much weeping and gnashing of teeth), it ultimately proved to be useless because of the problem outlined in this post. WebAuthn doesn't seem to be designed for 'split architecture'. Meaning that you must host your Web Application and your API on the same domain.
Because of this I am basically rethinking my entire approach and starting over trying to implement WebAuthn. Wish me luck!
Even as I type this answer I still have doubts. This just simply can't be the case can it? How are mobile applications supposed to implement WebAuthn if the FIDO2 exchange must happen on the same domain? Are mobile apps expected to load some kind of web view? Are all Web Applications expected to be hosted on the same domain as the Relying party? Or expected to load some sort of iframe? I am very confused, but determined to make WebAuthn work for me.
Upvotes: 1
Reputation: 1662
PublicKeyCredential.response
, after a create
call, will be an AuthenticatorAttestationResponse. On that object are the functions getPublicKey
and getAuthenticatorData
(see 5.2.1.1), which will get you the information that you need. But they do, indeed, both return ArrayBuffers.
You can base64-encode an ArrayBuffer, a
, with something like btoa(String.fromCharCode.apply(null, new Uint8Array(a)))
.
Upvotes: 2