Szczegółowe dane logowania dostępne do znalezienia

Dane logowania FIDO, takie jak klucze dostępu, mają zastępować hasła, ale większość z nich może też zapewnić użytkownikowi możliwość wpisania nazwy użytkownika. Umożliwia to użytkownikom uwierzytelnianie przez wybranie konta z listy kluczy dostępu do bieżącej witryny.

Wcześniejsze wersje kluczy bezpieczeństwa były zaprojektowane jako metody uwierzytelniania dwuetapowego i wymagały identyfikatorów potencjalnych danych uwierzytelniających, co wymagało podania nazwy użytkownika. Dane uwierzytelniające, które może znaleźć klucz bezpieczeństwa bez znajomości ich identyfikatora, są nazywane danymi możliwymi do znalezienia. Większość utworzonych dzisiaj danych logowania FIDO to możliwe do znalezienia dane uwierzytelniające. zwłaszcza kluczy dostępu przechowywanych w menedżerze haseł lub na nowoczesnym kluczu bezpieczeństwa.

Aby mieć pewność, że dane logowania są tworzone jako klucze dostępu (wykrywalne dane logowania), podczas ich tworzenia podaj residentKey i requireResidentKey.

Użytkownicy mogą używać danych logowania, które można wykryć, pomijając allowCredentials podczas uwierzytelniania za pomocą klucza dostępu. W takich przypadkach przeglądarka lub system wyświetlają użytkownikowi listę dostępnych kluczy dostępu, zidentyfikowanych przez właściwość user.name ustawioną w momencie utworzenia. Jeśli użytkownik wybierze jedną z nich, wartość user.id zostanie uwzględniona w podpisanym dokumencie. Serwer może następnie użyć tego lub zwrócony identyfikator danych logowania w celu wyszukania konta zamiast wpisanej nazwy użytkownika.

Interfejsy selektora kont, tak jak omówione wcześniej, nigdy nie wyświetlają niewykrywalnych kont dane logowania.

requireResidentKeyresidentKey

Aby utworzyć klucz dostępu, w systemie navigator.credentials.create() wpisz wartości authenticatorSelection.residentKey i authenticatorSelection.requireResidentKey za pomocą podanych niżej wartości.

async function register () {
  // ...

  const publicKeyCredentialCreationOptions = {
    // ...
    authenticatorSelection: {
      authenticatorAttachment: 'platform',
      residentKey: 'required',
      requireResidentKey: true,
    }
  };

  const credential = await navigator.credentials.create({
    publicKey: publicKeyCredentialCreationOptions
  });

  // This does not run until the user selects a passkey.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;

  // ...
}

residentKey:

  • 'required': musisz utworzyć dane logowania, które są możliwe do znalezienia. Jeśli nie można go utworzyć, zwracany jest element NotSupportedError.
  • 'preferred': RP preferuje tworzenie danych logowania możliwych do znalezienia, ale akceptuje dane logowania niemożliwe do znalezienia.
  • 'discouraged': RP woli utworzyć niewykrywalne dane logowania, ale akceptuje wykrywalne dane logowania.

requireResidentKey:

  • Ta właściwość jest zachowana ze względu na zgodność z poziomem 1 specyfikacji WebAuthn, czyli starszą wersją specyfikacji. Ustaw tę wartość na true, jeśli residentKey to 'required'. W przeciwnym razie ustaw ją na false.
.

allowCredentials

Reprezentanci użytkowników mogą używać allowCredentialsnavigator.credentials.get(), aby kontrolować uwierzytelnianie za pomocą klucza. Istnieją zwykle 3 rodzaje uwierzytelniania za pomocą kluczy dostępu:

Dzięki wykrywalności danych uwierzytelniających RP może wyświetlić modalny selektor konta, na którym użytkownik może wybrać konto, na które chce się zalogować, a następnie przejść weryfikację przez użytkownika. Jest to odpowiednie rozwiązanie w przypadku procesu uwierzytelniania za pomocą klucza, który jest inicjowany przez naciśnięcie przycisku przeznaczonego do uwierzytelniania za pomocą klucza.

Aby uzyskać taki efekt, pomiń parametr allowCredentials lub przekaż mu pusty tablic w funkcji navigator.credentials.get().

async function authenticate() {
  // ...

  const publicKeyCredentialRequestOptions = {
    // Server generated challenge:
    challenge: ****,
    // The same RP ID as used during registration:
    rpId: 'example.com',
    // You can omit `allowCredentials` as well:
    allowCredentials: []
  };

  const credential = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions,
    signal: abortController.signal
  });

  // This does not run until the user selects a passkey.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;
  
  // ...
}

Pokaż autouzupełnianie formularza klucza dostępu

Opisywany powyżej modalny selektor kont działa dobrze, jeśli większość użytkowników korzysta z kluczy dostępu i ma je dostępne na urządzeniu lokalnym. W przypadku użytkownika, który nie ma lokalnych kluczy dostępu, nadal wyświetla się okno modalne z prośbą o podanie klucza dostępu z innego urządzenia. Podczas przenoszenia użytkowników na klucze dostępu możesz unikać tego interfejsu w przypadku użytkowników, którzy nie skonfigurowali jeszcze kluczy.

Zamiast tego wybór klucza dostępu może zostać uwzględniony w autouzupełnianiu pól w tradycyjnym formularzu logowania razem z zapisanymi nazwami użytkowników i hasłami. Dzięki temu użytkownik z kluczem dostępu może „wypełnić” formularz logowania, wybierając klucz dostępu, użytkownicy z zapisanymi nazwami użytkowników i hasłami mogą wybrać te dane, a użytkownicy bez tych danych mogą wpisać swoją nazwę użytkownika i hasło.

Takie działanie jest idealne dla użytkowników, gdy w RPA trwa migracja z mieszanymi hasłami i kluczami.

Aby uzyskać takie działanie, oprócz przekazania pustego tablicy do właściwości allowCredentials lub pominięcia parametru, określ mediation: 'conditional' w przypadku navigator.credentials.get() i opatrz pole wejściowe HTML username atrybutem autocomplete="username webauthn" lub pole wejściowe password atrybutem autocomplete="password webauthn".

Wywołanie funkcji navigator.credentials.get() nie powoduje wyświetlenia interfejsu użytkownika, ale jeśli użytkownik zaznaczy pole do wprowadzania danych z adnotacją, wszystkie dostępne klucze dostępu zostaną uwzględnione w opcjach autouzupełniania. Jeśli użytkownik wybierze jedną z nich, przejdzie standardową weryfikację odblokowania urządzenia. Dopiero wtedy obietnica zwrócona przez .get() zostanie zrealizowana. Jeśli użytkownik nie wybierze klucza dostępu, obietnica nigdy nie zostanie zrealizowana.

async function authenticate() {
  // ...

  const publicKeyCredentialRequestOptions = {
    // Server generated challenge:
    challenge: ****,
    // The same RP ID as used during registration:
    rpId: 'example.com',
    // You can omit `allowCredentials` as well:
    allowCredentials: []
  };

  const cred = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions,
    signal: abortController.signal,
    // Specify 'conditional' to activate conditional UI
    mediation: 'conditional'
  });

  // This does not run until the user selects a passkey.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;
  
  // ...
}
<input type="text" name="username" autocomplete="username webauthn" ...>

Więcej informacji o tym, jak tworzyć takie rozwiązania, znajdziesz w ćwiczeniach Logowanie się za pomocą klucza dostępu przez autouzupełnianie formularzy oraz Wdrażanie kluczy dostępu z autouzupełnianiem formularzy w aplikacji internetowej.

Ponowne uwierzytelnianie

W niektórych przypadkach, np. gdy do ponownego uwierzytelnienia używane są klucze dostępu, identyfikator użytkownika jest już znany. W tym przypadku chcielibyśmy użyć klucza dostępu bez wyświetlania przez przeglądarkę lub system operacyjny dowolnej formy selektora konta. Aby to zrobić, przekaż listę identyfikatorów danych logowania w parametrze allowCredentials.

W takim przypadku, jeśli na urządzeniu są dostępne jakiekolwiek nazwane dane logowania, użytkownik od razu otrzyma prośbę o odblokowanie urządzenia. W przeciwnym razie użytkownik zobaczy prośbę o przedstawienie innego urządzenia (telefonu lub klucza bezpieczeństwa) z ważnymi danymi logowania.

Aby zapewnić wygodę użytkownikom, przygotuj listę identyfikatorów danych logowania użytkownika logującego się. RP powinien mieć możliwość wysłania zapytania do tych usług, ponieważ użytkownik jest już znany. Podaj identyfikatory danych logowania jako obiekty PublicKeyCredentialDescriptor w przypadku właściwości allowCredentials w elementach navigator.credentials.get().

async function authenticate() {
  // ...

  const publicKeyCredentialRequestOptions = {
    // Server generated challenge:
    challenge: ****,
    // The same RP ID as used during registration:
    rpId: 'example.com',
    // Provide a list of PublicKeyCredentialDescriptors:
    allowCredentials: [{
      id: ****,
      type: 'public-key',
      transports: [
        'internal',
        'hybrid'
      ]
    }, {
      id: ****,
      type: 'public-key',
      transports: [
        'internal',
        'hybrid'
      ]
    }, ...]
  };

  const credential = await navigator.credentials.get({
    publicKey: publicKeyCredentialRequestOptions,
    signal: abortController.signal
  });

  // This does not run until the user selects a passkey.
  const credential = {};
  credential.id = cred.id;
  credential.rawId = cred.id; // Pass a Base64URL encoded ID string.
  credential.type = cred.type;
  
  // ...
}

Obiekt PublicKeyCredentialDescriptor składa się z:

  • id: identyfikator poświadczeń klucza publicznego uzyskanych przez RP podczas rejestracji klucza dostępu.
  • type: to pole zwykle zawiera wartość 'public-key'.
  • transports: wskazówka dotycząca transportu obsługiwanego przez urządzenie zawierające te dane logowania. Jest ona używana przez przeglądarki do optymalizacji interfejsu, który prosi użytkownika o przedstawienie urządzenia zewnętrznego. Ta lista powinna zawierać wynik wywołania getTransports() podczas rejestracji poszczególnych danych logowania.

Podsumowanie

Dane logowania, które można znaleźć, znacznie ułatwiają logowanie się za pomocą klucza dostępu, ponieważ pozwalają pominąć wpisywanie nazwy użytkownika. Dzięki połączeniu funkcji residentKey, requireResidentKeyallowCredentials partnerzy reklamowi mogą korzystać z logowania, które:

  • Pokaż modalny selektor kont.
  • Wyświetlanie autouzupełniania formularza klucza dostępu.
  • Ponowne uwierzytelnianie.

Rozważnie korzystaj z możliwych do znalezienia danych logowania. Dzięki temu możesz zaprojektować zaawansowane funkcje logowania za pomocą klucza dostępu, które będą wygodne dla użytkowników i zwiększać ich zaangażowanie.