Utrzymywanie spójności kluczy dostępu z danymi logowania na serwerze za pomocą interfejsu Signal API

Data publikacji: 12 listopada 2024 r.

Interfejs WebAuthn Signal API pozwala stronom powiązanym sygnalizować istniejące dane logowania do połączonych dostawców kluczy dostępu. Dzięki temu dostawca kluczy dostępu może zaktualizować lub usunąć z miejsca do przechowywania nieprawidłowe lub cofnięte klucze dostępu, aby nie były już dostępne dla użytkowników.

Zgodność

Chrome na komputerze obsługuje interfejs Signal API od wersji 132. Menedżer haseł Google może aktualizować klucze dostępu zgodnie z danymi sygnału. W przypadku dostawców kluczy dostępu korzystających z rozszerzeń Chrome to oni decydują, czy będą uwzględniać sygnał.

Obsługa Chrome na Androidzie pojawi się wkrótce.

Safari obsługuje tę funkcję, ale nie jest ona jeszcze wdrożona. Firefox jeszcze nie podzielił się swoimi spostrzeżeniami.

Tło

Gdy tworzysz klucz dostępu (wykrywalne dane logowania), metadane takie jak nazwa użytkownika i wyświetlana nazwa są zapisywane w usłudze klucza dostępu (np. w menedżerze haseł) wraz z kluczem prywatnym, a dane logowania z kluczem publicznym są zapisywane na serwerze po stronie zaufanej. Zapisywanie nazwy użytkownika i wyświetlanej nazwy pomaga użytkownikowi określić, którego z oferowanych kluczy dostępu użyć do zalogowania się, gdy pojawi się odpowiedni komunikat. Jest to szczególnie przydatne, gdy użytkownik ma więcej niż 2 klucze dostępu od różnych dostawców.

Są jednak sytuacje, w których niezgodności między listą kluczy dostępu dostawcy a listą poświadczeń serwera mogą wprowadzać w błąd.

Pierwszy przypadek to sytuacja, gdy użytkownik usuwa dane logowania na serwerze, nie zmieniając klucza dostępu u dostawcy. Gdy użytkownik następnym razem spróbuje zalogować się przy użyciu klucza dostępu, dostawca kluczy dostępu nadal będzie wyświetlał ten klucz. Próba zalogowania się się nie powiedzie, ponieważ serwer nie będzie mógł zweryfikować klucza publicznego, który został usunięty.

Drugi przypadek to sytuacja, gdy użytkownik zaktualizuje swoją nazwę użytkownika lub nazwę wyświetlaną na serwerze. Gdy użytkownik następnym razem spróbuje się zalogować, klucz dostępu w usługodawcy kluczy dostępu będzie nadal wyświetlać starą nazwę użytkownika i wyświetlaną nazwę, mimo że zostały one zaktualizowane na serwerze. W najlepszym przypadku powinny być zsynchronizowane.

Signal API

Interfejs Signal API to interfejs WebAuthn API, który rozwiązuje te problemy, pozwalając dostawcom usług uwierzytelniania na sygnalizowanie zmian dostawcy kluczy dostępu. Możesz to zrobić na 3 sposoby:

sygnalizuje, że dane logowania nie istnieją;

const credential = await navigator.credentials.get({ ... });
const payload = credential.toJSON();

const result = await fetch('/login', { ... });

// Detect authentication failure due to lack of the credential
if (result.status === 404) {
  // Feature detection
  if (PublicKeyCredential.signalUnknownCredential) {
    await PublicKeyCredential.signalUnknownCredential({
      rpId: "example.com",
      credentialId: "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA" // base64url encoded credential ID
    });
  } else {
    // Encourage the user to delete the passkey from the password manager nevertheless.
    ...
  }
}

Wywołując PublicKeyCredential.signalUnknownCredential() z identyfikatorem RP i identyfikatorem danych logowania, RP może poinformować dostawcę kluczy dostępu, że określone dane logowania zostały usunięte lub nie istnieją. To dostawca klucza dostępu decyduje, jak postąpić z tym sygnałem, ale klucz dostępu powiązany z tym sygnałem powinien zostać usunięty, aby użytkownik nie mógł się zalogować za pomocą klucza dostępu, ponieważ powiązane z nim dane uwierzytelniające nie istnieją.

Interfejs API można wywołać w przypadku, gdy logowanie za pomocą klucza nie powiodło się z powodu braku danych logowania. Dzięki temu RP może uniemożliwić użytkownikowi próbę zalogowania się za pomocą klucza dostępu, który nie jest powiązany z danymi logowania. W przeciwieństwie do metody signalAllAcceptedCredentials ta metoda nie wymaga przekazywania całej listy identyfikatorów danych logowania, dlatego należy jej używać, gdy użytkownik nie jest uwierzytelniony, aby uniknąć ujawniania liczby kluczy dostępu danego użytkownika.

Okno wyświetlane po usunięciu klucza dostępu z Menedżera haseł Google w Chrome.
Okno wyświetlane po usunięciu klucza dostępu z Menedżera haseł Google w Chrome.

Wyświetl listę zapisanych danych logowania

// After a user deletes a passkey or a user is signed in.

// Feature detection
if (PublicKeyCredential.signalAllAcceptedCredentials) {
  await PublicKeyCredential.signalAllAcceptedCredentials({
    rpId: "example.com",
    userId: "M2YPl-KGnA8", // base64url encoded user ID
    allAcceptedCredentialIds: [ // A list of base64url encoded credential IDs
      "vI0qOggiE3OT01ZRWBYz5l4MEgU0c7PmAA",
      ...
    ]
  });
}

Wywołując funkcję PublicKeyCredential.signalAllAcceptedCredentials() z identyfikatorem RP, identyfikatorem użytkownika i listą identyfikatorów danych logowania, dostawca kluczy dostępu może poinformować dostawcę kluczy dostępu o pozostałych danych logowania w swoim magazynie. To, jak dostawca kluczy dostępu ma sobie poradzić z tym sygnałem, zależy od niego, ale klucze dostępu, które nie pasują do tej listy, powinny zostać usunięte, aby użytkownik nie widział kluczy dostępu podczas logowania, do których nie ma powiązanych danych logowania.

Ten interfejs API powinien być wywoływany po usunięciu przez użytkownika klucza dostępu na RP oraz po każdym zalogowaniu, aby dostawca kluczy dostępu mógł zachować zsynchronizowaną listę kluczy dostępu.

sygnał zaktualizowany nazwa użytkownika i wyświetlana nazwa

// After a user updated their username and/or display name
// or a user is signed in.

// Feature detection
if (PublicKeyCredential.signalCurrentUserDetails) {
  await PublicKeyCredential.signalCurrentUserDetails({
    rpId: "example.com",
    userId: "M2YPl-KGnA8", // base64url encoded user ID
    name: "a.new.email.address@example.com", // username
    displayName: "J. Doe"
  });
} else {
}

Wywołując PublicKeyCredential.signalCurrentUserDetails() z identyfikatorem RP, identyfikatorem użytkownika, nazwą użytkownika i wyświetlaną nazwą, RP może poinformować dostawcę kluczy dostępu o zaktualizowanych informacjach o użytkowniku. To od dostawcy kluczy dostępu zależy, jak potraktuje on ten sygnał, ale klucze dostępu należące do użytkownika powinny zostać zaktualizowane o nowe informacje o użytkowniku.

Ten interfejs API może być wywoływany po zaktualizowaniu nazwy użytkownika lub wyświetlanej nazwy użytkownika oraz przy każdym logowaniu, aby dostawca klucza dostępu mógł utrzymywać te informacje w zsynchronizowanym stanie z serwerem.

Okno wyświetlane po zaktualizowaniu metadanych klucza w Menedżerze haseł Google w Chrome.
Okno wyświetlane po zaktualizowaniu metadanych klucza dostępu w Menedżerze haseł Google w Chrome.

Podsumowanie

Interfejs Signal API pomaga tworzyć lepsze klucze dostępu, eliminując ryzyko nieoczekiwanego niepowodzenia logowania. Dzięki interfejsowi Signal API strony ufające mogą sygnalizować listę istniejących danych logowania i ich metadanych, aby móc utrzymywać klucze dostępu u dostawcy kluczy w zsynchronizowanym stanie.

Aby dowiedzieć się więcej o kluczach dostępu, zacznij od artykułu Logowanie bez hasła za pomocą kluczy dostępu.