Open willbarkoff opened 3 years ago
Ok, so looking into this it really doesn't seem too hard. The two main go libraries to do this are duo-labs/webauthn and koesie10/webauthn. JS implements it really nicely (https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API).
The only issue is actually debugging this. You need a secure context, and the way that we currently do local development, it isn't considered a secure context. (This was actually the main thing stopping me from doing #87).
Looking into this a bit more, it's actually not too hard. You need to generate a local certificate and have your computer trust it. Instructions are here, and I'll probably add them to the README at some point.
Alternatively, if you're using Chrome, you can go to chrome://flags and add "http://app.myhomework.invalid" to the list of "Insecure origins treated as secure". There's also probably a Firefox alternative with about:config.
Turns out it wasn't too hard at all :)
I'll add instructions to the README
I've implemented like half of this so far. The current plan is that a user must have TOTP setup to set up WebAuthn. A user may have both TOTP and WebAuthn setup. A user cannot have WebAuthn setup without TOTP.
Here's what's been done so far, and what needs to be done:
auth/login
. While TOTP can be reasonably acheived in one request (send the username, password, and OTP all together), WebAuthn cannot. This is because TOTP is nondeterministic with respect to the server; however, WebAuthn is deterministic with respect to the server. We need to somehow send the client the data to sign, and the client needs to send back the signed data.auth/login
can return some sort of "pending 2fa" response, with the data to sign, then we simply add a key to the redis store with the pending login data, and the client authenticates with WebAuthn, and makes a request to auth/2fa/login/webauthn
or something. The TOTP code could also be refactored to follow this layout. This would allow further flexibility for 2fa in the future.auth/login
, and gets the WebAuthn data. Now computer B sends a request to auth/login
and the server generates new WebAuthn data. This overwrites the previous WebAuthn data stored in redis. Now computer A sends a request to auth/2fa/login/webauthn
with the correct data that was sent to it. It is marked as incorrect because Computer B's request overwrote it. This could be fixed by assigning each call to auth/login
a unique ID; but that seems like it might be overkill. @thatoddmailbox, do you have any thoughts on this?webauthn
and 2fa
tables.Since these features aren't finished yet, I've pushed them to MyHomeworkSpace/client@webauthn and MyHomeworkSpace/api-server@webauthn
It would be amazing if we could support hardware tokens with U2F :lock:.