allow sign in via webauthn credentials

The flow of the code is roughly as follows:

  user clicks button on webauthn page
  js sends GET request
  python reads GET request, sets up login challenge
  python returns login challenge in response
  js reads GET response, passes login challenge to browser
  browser asks user to touch yubikey
  browser returns yubikey challenge response data to js
  js sends POST request with yubikey challenge response data
  python reads yubikey challenge and compares with users creds from db
  if its a match, python signs user in

The login challenge is a PublicKeyCredentialRequestOptions: [1]
The browser function we call is navigator.credentials.get(): [2]
The response to the challenge from the browser is a PublicKeyCredential: [3]

The python server does all the work setting those up and tearing them
back down again (and checking them against the values we have stored in
the database), but we need to do work to convert them to-and-from CBOR.

[1] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredentialRequestOptions
[2] https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get
[3] https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential
This commit is contained in:
Leo Hemsted
2021-05-14 17:37:57 +01:00
parent c203f624ca
commit c26a596839
4 changed files with 125 additions and 12 deletions

View File

@@ -157,3 +157,27 @@ def test_complete_register_handles_missing_state(
assert response.status_code == 400
assert cbor.decode(response.data) == 'No registration in progress'
def test_begin_authentication_returns_encoded_options(client):
pass
def test_begin_authentication_includes_existing_credentials(client):
pass
def test_begin_authentication_stores_state_in_session(client):
pass
def test_complete_authentication_logs_user_in(client):
pass
def test_complete_authentication_403s_if_key_isnt_in_users_credentials(client):
pass
def test_complete_authentication_clears_session(client):
pass

View File

@@ -341,6 +341,8 @@ EXCLUDED_ENDPOINTS = tuple(map(Navigation.get_endpoint_with_blueprint, {
'view_template_versions',
'webauthn_begin_register',
'webauthn_complete_register',
'webauthn_begin_authentication',
'webauthn_complete_authentication',
'who_can_use_notify',
'who_its_for',
'write_new_broadcast',