Introductie van hints, gerelateerde oorsprongsverzoeken en JSON-serialisatie voor WebAuthn in Chrome

Chrome 128 en 129 introduceren interessante nieuwe functies voor WebAuthn, de onderliggende API voor het bouwen van op wachtwoorden gebaseerde authenticatiesystemen.

  • Hints : Hints geven Relying Party's (RP's) meer controle over de WebAuthn-gebruikersinterface in de browser. Ze zijn vooral handig voor zakelijke gebruikers die beveiligingssleutels willen gebruiken.
  • Gerelateerde oorsprongsverzoeken : Met gerelateerde oorsprongsverzoeken kunnen RP's toegangssleutels geldig maken op meerdere domeinen. Als u meerdere sites beheert, kunt u uw gebruikers nu toestaan ​​hun toegangssleutel op al uw sites te hergebruiken, waardoor problemen met inloggen worden voorkomen.
  • JSON-serialisatie : met JSON-serialisatie-API's kunt u de frontendcode van een RP vereenvoudigen door opties en referenties te coderen en decoderen die van en naar de WebAuthn API worden doorgegeven.

Tips

Met hints kunnen vertrouwende partijen (RP) nu gebruikersinterfacevoorkeuren opgeven voor het maken van een toegangssleutel of voor authenticatie met een toegangssleutel.

Voorheen, wanneer een RP de authenticator wilde beperken die de gebruiker kon gebruiken om een ​​toegangssleutel aan te maken of waarmee hij zich kon authenticeren, kon hij authenticatorSelection.authenticatorAttachment gebruiken om "platform" of "cross-platform" te specificeren. Hiermee beperkte hij de authenticator respectievelijk tot een platformauthenticator of een roamingauthenticator . Met hints kan deze specificatie flexibeler zijn.

De RP kan optionele hints gebruiken in PublicKeyCredentialCreationOptions of PublicKeyCredentialRequestOptions om "security-key" , "client-device" en "hybrid" in een voorkeursvolgorde in een array te specificeren.

Hieronder ziet u een voorbeeld van een verzoek voor het aanmaken van inloggegevens dat de voorkeur geeft aan "cross-platform" authenticators met "security-key" als hint. Dit geeft Chrome de opdracht een gebruikersinterface met beveiligingssleutels weer te geven voor zakelijke gebruikers.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    hints: ['security-key'],
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
Als u 'security-key' als hint opgeeft, toont de browser een dialoogvenster dat gericht is op de beveiligingssleutel.
Als u 'security-key' als hint opgeeft, toont de browser een dialoogvenster dat gericht is op de beveiligingssleutel.

Wanneer een RP prioriteit wil geven aan een verificatiescenario op meerdere apparaten, kan hij een authenticatieverzoek versturen dat de voorkeur geeft aan "cross-platform" authenticators met "hybrid" als hint.

const credential = await navigator.credentials.create({
  publicKey: {
    challenge: *****,
    residentKey: true,
    hints: ['hybrid']
    authenticatorSelection: {
      authenticatorAttachment: 'cross-platform'
    }
  }
});
Door 'hybride' als hint op te geven, toont de browser een dialoogvenster dat gericht is op inloggen op meerdere apparaten.
Door 'hybride' als hint op te geven, toont de browser een dialoogvenster dat gericht is op inloggen op meerdere apparaten.

Met Related Origin Requests kunnen RP's wachtwoorden van meerdere domeinen bruikbaar maken. Het opzetten van een gecentraliseerde inlogervaring en het gebruik van federatieprotocollen blijven de aanbevolen oplossing voor de meeste sites. Maar als u meerdere domeinen beheert en federatie niet mogelijk is, kunnen Related Origins een oplossing zijn.

Alle WebAuthn-aanvragen moeten een Relying Party ID (RP ID) specificeren en alle toegangssleutels zijn gekoppeld aan één RP ID. Traditioneel kon een oorsprong alleen een RP ID specificeren op basis van zijn domein, dus in dat geval kon www.example.co.uk een RP ID van example.co.uk specificeren, maar niet example.com . Met Related Origin Requests kan een geclaimde RP ID worden gevalideerd door een bekend JSON-bestand op te halen op /.well-known/webauthn van het doeldomein. Zo kunnen example.co.uk (en example.in , example.de , enzovoort) allemaal een RP ID van example.com gebruiken als example.com deze in de volgende notatie specificeert:

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"
  ]
}

Leer hoe u Related Origin Requests instelt op Sta hergebruik van wachtwoorden op al uw sites toe met Related Origin Requests .

JSON-serialisatie

WebAuthn-aanvraag- en -responsobjecten bevatten meerdere velden met onbewerkte binaire gegevens in een ArrayBuffer, zoals de referentie-ID, gebruikers-ID of challenge. Als een website JSON wil gebruiken om deze gegevens met de server uit te wisselen, moeten de binaire gegevens eerst worden gecodeerd, bijvoorbeeld met Base64URL. Dit voegt onnodige complexiteit toe voor ontwikkelaars die wachtwoordsleutels op hun websites willen gaan gebruiken.

WebAuthn biedt nu API's om PublicKeyCredentialCreationOptions en PublicKeyCredentialRequestOptions WebAuthn-aanvraagobjecten rechtstreeks vanuit JSON te parseren en de PublicKeyCredential- respons rechtstreeks in JSON te serialiseren. Alle velden met een ArrayBuffer-waarde die onbewerkte binaire gegevens bevatten, worden automatisch geconverteerd van of naar hun Base64URL-gecodeerde waarden. Deze API's zijn beschikbaar vanaf Chrome 129.

Voordat u een toegangssleutel maakt, haalt u een JSON-gecodeerd PublicKeyCredentialCreationOptions -object op van de server en decodeert u dit met PublicKeyCredential.parseCreationOptionsFromJSON() .

Browser Support

  • Chroom: 129.
  • Rand: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

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,
  });
  ...

Nadat u een toegangscode hebt aangemaakt, codeert u de resulterende referentie met toJSON() zodat deze naar de server kan worden verzonden.

Browser Support

  • Chroom: 129.
  • Rand: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

  ...
  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);
  ...

Voordat u authenticatie uitvoert met een toegangssleutel, haalt u een JSON-gecodeerde PublicKeyRequestCreationOptions op van de server en decodeert u deze met PublicKeyCredential.parseRequestOptionsFromJSON() .

Browser Support

  • Chroom: 129.
  • Rand: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

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
  });
  ...

Nadat u bent geverifieerd met een wachtwoord, codeert u de resulterende referentie met toJSON() methode, zodat deze naar de server kan worden verzonden.

Browser Support

  • Chroom: 129.
  • Rand: 129.
  • Firefox: 119.
  • Safari: 18.4.

Source

  ...
  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);
  ...

Meer informatie

Voor meer informatie over WebAuthn en wachtwoordsleutels kunt u de volgende bronnen raadplegen: