Przedstawiamy wskazówki, powiązane żądania dotyczące źródła i serializację JSON dla WebAuthn w Chrome

Chrome 128 i 129 wprowadzają nowe, ekscytujące funkcje dla WebAuthn – interfejsu API służącego do tworzenia systemów uwierzytelniania na podstawie klucza dostępu.

  • Wskazówki: informacje pozwalające stronom korzystającym z usługi (RP) lepiej kontrolować interfejs WebAuthn w przeglądarce. Są one szczególnie przydatne dla użytkowników biznesowych, którzy chcą używać kluczy bezpieczeństwa.
  • Powiązane żądania pochodzenia: dzięki nim dostawcy kluczy mogą udostępniać klucze dostępu w wielu domenach. Jeśli masz wiele witryn, możesz teraz umożliwić użytkownikom ponowne używanie kluczy dostępu w tych witrynach, co ułatwia logowanie.
  • Serializowanie danych w formacie JSON: interfejsy API do serializacji danych w formacie JSON umożliwiają uproszczenie kodu front-end RP przez kodowanie i dekodowanie opcji oraz poświadczeń przekazywanych do interfejsu WebAuthn API i z niego.

Wskazówki

Dzięki hints strony trzecie (RP) mogą teraz określać ustawienia interfejsu użytkownika dotyczące tworzenia kluczy dostępu i uwierzytelniania za ich pomocą.

Wcześniej, gdy RP chciał ograniczyć uwierzytelnianie za pomocą uwierzytelniania, którego użytkownik może używać do tworzenia kluczy dostępu lub uwierzytelniania, mógł użyć authenticatorSelection.authenticatorAttachment, aby określić "platform" lub "cross-platform". W odpowiednich przypadkach ograniczają one aplikację uwierzytelniającą do aplikacji uwierzytelniającej na platformie lub aplikacji uwierzytelniającej w roamingu. Dzięki hints ta specyfikacja może być bardziej elastyczna.

RP może użyć opcjonalnego parametru hints w elementach PublicKeyCredentialCreationOptions lub PublicKeyCredentialRequestOptions, aby określić elementy "security-key", "client-device""hybrid" w kolejności preferencji w tablicy.

Oto przykład żądania tworzenia danych logowania, które preferuje uwierzytelniacze "cross-platform" z podpowiedzią "security-key". Ta opcja informuje Chrome, aby wyświetlał interfejs skupiony na kluczu bezpieczeństwa dla użytkowników biznesowych.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
Jeśli jako podpowiedź podasz „security-key”, przeglądarka wyświetli okno z opcjami dotyczącymi klucza bezpieczeństwa.
Jeśli jako podpowiedź podasz „security-key”, przeglądarka wyświetli okno dialogowe z opcjami dotyczącymi klucza bezpieczeństwa.

Jeśli RP chce nadać priorytet weryfikacji na różnych urządzeniach, może wysłać żądanie uwierzytelniania, które preferuje uwierzytelnianie "cross-platform" z podpowiedzią "hybrid".

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
Jeśli jako podpowiedź podasz „hybryda”, przeglądarka wyświetli okno logowania na różnych urządzeniach.
Jeśli jako podpowiedź podasz „hybrydowy”, przeglądarka wyświetli okno logowania na różnych urządzeniach.

Dzięki powiązanym żądaniom źródłowym RP mogą udostępniać klucze dostępu w kilku domenach. W przypadku większości witryn zaleca się tworzenie scentralizowanych procesów logowania i korzystanie z protokołów federacyjnych. Jeśli jednak masz wiele domen i nie możesz utworzyć federacji, rozwiązaniem mogą być powiązane źródła.

Wszystkie żądania WebAuthn muszą zawierać identyfikator strony uwierzytelniającej (RP ID), a wszystkie klucze dostępu są powiązane z jednym identyfikatorem RP. Do tej pory pochodzenie mogło określać identyfikator RP tylko na podstawie domeny, więc w tym przypadku www.example.co.uk mogło podać identyfikator RP example.co.uk, ale nie example.com. W przypadku żądań z powiązanego źródła można zweryfikować zadeklarowany identyfikator RP, pobierając znany plik JSON z domeny docelowej, który znajduje się pod adresem /.well-known/webauthn. W związku z tym example.co.uk (i example.in, example.de itd.) może używać identyfikatora RP example.com, jeśli example.com określa je w takim formacie:

Adres URL: https://example.com/.well-known/webauthn

{
  "origins": [
    "https://example.co.uk",
    "https://example.de",
    "https://example.sg",
    "https://example.net",
    "https://exampledelivery.com",
    "https://exampledelivery.co.uk",
    "https://exampledelivery.de",
    "https://exampledelivery.sg",
    "https://myexamplerewards.com",
    "https://examplecars.com"
  ]
}

Dowiedz się, jak skonfigurować żądania powiązanych źródeł na stronie Zezwalaj na ponowne użycie klucza dostępu na stronach z żądaniami powiązanych źródeł.

Serializacja w formacie JSON

Obiekty żądania i odpowiedzi WebAuthn zawierają wiele pól z nieprzetworzonymi danymi binarnymi w ArrayBuffer, np. identyfikator danych logowania, identyfikator użytkownika lub wyzwanie. Jeśli witryna chce używać formatu JSON do wymiany tych danych z serwerem, dane binarne muszą zostać najpierw zakodowane, np. za pomocą Base64URL. Spowoduje to niepotrzebne komplikowanie pracy deweloperów, którzy chcą zacząć używać kluczy w swoich witrynach.

WebAuthn udostępnia teraz interfejsy API do analizowania obiektów żądań WebAuthn bezpośrednio z plików JSON (PublicKeyCredentialCreationOptions) i serializowania odpowiedzi PublicKeyCredentialRequestOptions (PublicKeyCredential) bezpośrednio w formacie JSON. Wszystkie pola o wartości ArrayBuffer, które zawierają nieprzetworzone dane binarne, są automatycznie konwertowane z wartości zakodowanych w formacie Base64URL lub do nich. Te interfejsy API są dostępne od wersji 129.

Zanim utworzysz klucz dostępu, pobierz z serwera zakodowany w formacie JSON obiekt PublicKeyCredentialCreationOptions i odkoduj go za pomocą funkcji PublicKeyCredential.parseCreationOptionsFromJSON().

Obsługa przeglądarek

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: nieobsługiwane.

Źródło

export async function registerCredential() {

  // Fetch encoded `PublicKeyCredentialCreationOptions`
  // and JSON decode it.
  const options = await fetch('/auth/registerRequest').json();

  // Decode `PublicKeyCredentialCreationOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseCreationOptionsFromJSON(options);  

  // Invoke the WebAuthn create() function.
  const cred = await navigator.credentials.create({
    publicKey: decodedOptions,
  });
  ...

Po utworzeniu klucza dostępu zakoduj uzyskane dane logowania za pomocą funkcji toJSON(), aby można je było wysłać na serwer.

Obsługa przeglądarek

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: nieobsługiwane.

Źródło

  ...
  const cred = await navigator.credentials.create({
    publicKey: options,
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch('/auth/registerResponse', credential);
  ...

Przed uwierzytelnieniem za pomocą klucza dostępu pobierz z serwera zakodowany w formacie JSON plik PublicKeyRequestCreationOptions i odkoduj go za pomocą funkcji PublicKeyCredential.parseRequestOptionsFromJSON().

Obsługa przeglądarek

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: nieobsługiwane.

Źródło

export async function authenticate() {

  // Fetch encoded `PublicKeyCredentialRequestOptions`
  // and JSON decode it.
  const options = await fetch('/auth/signinRequest').json();

  // Decode `PublicKeyCredentialRequestOptions` JSON object
  const decodedOptions = PublicKeyCredential.parseRequestOptionsFromJSON(options);

  // Invoke the WebAuthn get() function.
  const cred = await navigator.credentials.get({
    publicKey: options
  });
  ...

Po uwierzytelnieniu za pomocą klucza dostępu zakoduj uzyskane dane uwierzytelniające za pomocą metody toJSON(), aby można je było wysłać na serwer.

Obsługa przeglądarek

  • Chrome: 129.
  • Edge: 129.
  • Firefox: 119.
  • Safari: nieobsługiwane.

Źródło

  ...
  const cred = await navigator.credentials.get({
    publicKey: options
  });

  // Encode the credential to JSON and stringify
  const credential = JSON.stringify(cred.toJSON());

  // Send the encoded credential to the server
  await fetch(`/auth/signinResponse`, credential);
  ...

Więcej informacji

Więcej informacji o WebAuthn i kluczach dostępu znajdziesz w tych materiałach: