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 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: za pomocą takich żądań 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 po stronie klienta, ponieważ kod ten koduje i dekoduje opcje oraz poświadczenia przekazywane 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.

W ramach grupy objętej ograniczeniami można użyć opcjonalnego hints w PublicKeyCredentialCreationOptions lub PublicKeyCredentialRequestOptions, aby określić "security-key", "client-device" i "hybrid" w preferowanej kolejności w tablicy.

Poniżej znajduje się przykładowe żądanie utworzenia danych logowania, które preferuje uwierzytelnianie "cross-platform" ze wskazówką "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. Stworzenie scentralizowanego środowiska logowania i korzystanie z protokołów federacji pozostaje zalecanym rozwiązaniem w przypadku większości witryn. 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ą określać identyfikator jednostki uzależnionej (identyfikator RP), a wszystkie klucze dostępu są powiązane z jednym identyfikatorem RP. Tradycyjnie źródło mogło określać identyfikator RP tylko na podstawie swojej domeny, więc w takim przypadku www.example.co.uk może określać identyfikator RP o wartości 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. Oznacza to, że example.co.uk (i example.in, example.de itd.) mogą używać identyfikatora RP example.com, jeśli example.com podaje 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ązanego źródła na stronie Zezwalaj na ponowne użycie klucza dostępu na stronach z żądaniami powiązanego źródła.

Serializacja 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ą najpierw zostać zakodowane, np. za pomocą Base64URL. Spowoduje to niepotrzebne komplikowanie pracy deweloperów, którzy chcą zacząć używać kluczy w swoich witrynach.

WebAuthn oferuje teraz interfejsy API umożliwiające analizę obiektów PublicKeyCredentialCreationOptions i PublicKeyCredentialRequestOptions bezpośrednio z poziomu JSON oraz zserializowanie odpowiedzi PublicKeyCredential bezpośrednio do formatu JSON. Wszystkie pola o wartościach SlateBuffer, które zawierają nieprzetworzone dane binarne, są automatycznie konwertowane z lub na wartości zakodowane w Base64URL. Te interfejsy API są dostępne od wersji 129.

Zanim utworzysz klucz dostępu, pobierz z serwera obiekt PublicKeyCredentialCreationOptions zakodowany w formacie JSON i zdekoduj go za pomocą 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);
  ...

Zanim uwierzytelnisz się 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: