Delen via


Gebruiksvoorbeelden voor wachtwoordsleutels

In dit onderwerp worden enkele use cases voor wachtwoordsleutels beschreven.

Gebruikssituatie 1: Opstarten

Bootstrapping van een account op internet.

1.1: De gebruiker verifiëren

Deze sectie is van toepassing wanneer de relying party (RP) nog niet weet wie het clientapparaat beheert. Er is geen browserartefact beschikbaar voor de RP (zoals een cookie of een referentie-id in lokale opslag), hoewel we ervan uitgaan dat de gebruiker een bestaand account met de RP heeft.

Als u een account wilt opstarten, dient u de gebruiker een aanmeldingspagina te laten zien.

Vraag eerst de gebruiker om zijn account-id; meestal een gebruikersnaam of e-mailadres.

Aanmelden

Als u de gebruikersinterface voor automatisch doorvoeren voor wachtwoordsleutels wilt ondersteunen, moet u het volgende doen:

  1. Voeg de username en webauthn waarde toe aan eventuele bestaande aantekeningen voor automatisch aanvullen in het invoerveld gebruikersnaam.
<div>
  <label for="username">Username:</label>
  <input name="username" id="loginform.username"
         autocomplete="username webauthn">
</div>
  1. Bij het laden van de pagina gebruikt u een if instructie om te controleren of de auto-invul-UI (voorwaardelijke bemiddeling) beschikbaar is, waarna u navigator.credentials.get() aanroept met mediation: "conditional" en userVerification: "preferred".
  <script>
    (async () => {
      if (
      typeof window.PublicKeyCredential !== 'undefined'
      && typeof window.PublicKeyCredential.isConditionalMediationAvailable === 'function'
      ) {
        const available = await PublicKeyCredential.isConditionalMediationAvailable();

      if (available) {
          try {
            // Retrieve authentication options for `navigator.credentials.get()`
            // from your server.
            const authOptions = await getAuthenticationOptions();
      // This call to `navigator.credentials.get()` is "set and forget."
      // The Promise will resolve only if the user successfully interacts
      // with the browser's autofill UI to select a passkey.
      const webAuthnResponse = await navigator.credentials.get({
          mediation: "conditional",
      publicKey: {
          ...authOptions,
          // See note about userVerification below.
          userVerification: "preferred",
              }
            });
      // Send the response to your server for verification, and
      // authenticate the user if the response is valid.
      await verifyAutoFillResponse(webAuthnResponse);
          } catch (err) {
          console.error('Error with conditional UI:', err);
          }
        }
      }
    })();
  </script>

Het bovenstaande zorgt ervoor dat het volgende gebeurt:

  • Haal de verificatieopties van uw server op. Retourneer ten minste een willekeurige challenge en rpId die met dit verificatieverzoek geassocieerd zijn.
  • Wanneer de gebruiker interageert met uw gebruikersnaamveld, controleert de browser en het platform of er een passkey bestaat (in de platformauthenticator) die kan worden gebruikt met de vertrouwende partij.
  • Als dat het geval is , wordt de wachtwoordsleutel aan de gebruiker gepresenteerd als optie om te kiezen (samen met andere referenties die automatisch kunnen worden ingevuld, zoals gebruikersnamen die zijn opgeslagen in wachtwoordbeheer van de browser). De browser/het platform kan een gebruikersinterface weergeven die vergelijkbaar is met de gebruikersinterface die hieronder wordt weergegeven. Hoewel het exacte uiterlijk en gevoel variëren van het ene platform of apparaatontwerp naar het andere:

Aanmelden met wachtwoordsleutel

  • Als de gebruiker de wachtwoordsleutel selecteert, leidt de gebruikersinterface van het platform de gebruiker door middel van een verificatiecontrole van gebruikers (vaak biometrische gegevens).
  • Als de gebruiker succesvol de verificatie doorstaat, slaagt de navigator.credentials.get()-aanroep en geeft een WebAuthn-reactie terug.
  • Als de gebruiker een andere referentie dan een passkey selecteert, kiest de browser/het platform een passende actie (zoals het automatisch invullen van de gebruikersnaam) en wordt de navigator.credentials.get()-aanroep niet opgelost.
  • Als de gebruiker de optie Wachtwoordsleutel van een ander apparaat selecteert (de exacte tekst verschilt enigszins per platform), leidt de browser/het platform de gebruiker door een FIDO2-beveiligingssleutel of de CDA-stroom (Cross-Device Authentication) te gebruiken om een wachtwoordsleutel van hun smartphone of tablet te gebruiken om een WebAuthn-antwoord te geven op de navigator.credentials.get() oproep.
  • Verzend het WebAuthn-antwoord naar uw server voor verificatie en aanvullende beveiligingscontroles. Als alle controles zijn geslaagd, start u een geverifieerde sessie voor deze gebruiker.

Dit is de reden waarom dit de voorwaardelijke gebruikersinterface (of, vaker, de autovervollediging gebruikersinterface) van WebAuthn wordt genoemd: de gebruikersinterface van de platformauthenticatie die de gebruiker door de verificatie leidt of via hun telefoon, wordt alleen weergegeven als de gebruiker een toegangssleutel op dit apparaat heeft (of de optie 'een ander apparaat' kiest).

Zoals u kunt zien, slaagt de aanroep in deze modus, of het slaagt niet omdat het navigator.credentials.get() nooit wordt opgelost. Als dit lukt, wordt in het resultaat van de aanroep zowel een gebruikers-id als een ondertekende WebAuthn-assertie weergegeven, die door de relying party (RP) wordt gebruikt om de gebruiker te verifiëren.

Als de aanroep niet lukt, moet u een verouderde gebruikersverificatie uitvoeren. U krijgt een gebruikersnaam van deze eerste pagina en op de volgende pagina's biedt u vervolgens de juiste vervolg inloguitdagingen (zoals wachtwoorden, reageren op sms-uitdagingen, enzovoort) aan de gebruiker. Dit kunnen stappen voor accountherstel bevatten voor het geval de gebruiker zijn wachtwoord is vergeten of anders niet in staat is om de reguliere aanmeldingsuitdagingen op te lossen. Zodra de gebruiker alle aanmeldingsuitdagingen heeft doorstaan, worden ze beschouwd als geverifieerd en aangemeld.

Wanneer de gebruiker nog geen account met de relying party (RP) heeft, geeft u de gebruiker meestal de optie op de aanmeldingspagina om een account te maken. Als de gebruiker deze optie kiest, verzamelt u de benodigde gegevens van hen om een nieuw account te openen. Als ze een nieuw account hebben geopend, worden ze ook beschouwd als geverifieerd en aangemeld.

Zodra de gebruiker is aangemeld, kan het tijd zijn om een nieuwe wachtwoordsleutel in te stellen. Doe dit voor een van de volgende gevallen:

  • De gebruiker heeft hun account op het apparaat ingesteld door niet-passkey aanmeldingsmethoden (zoals het gebruik van een wachtwoord) te gebruiken.
  • De gebruiker heeft zojuist een nieuw account aangemaakt bij de relying party (RP) en wordt als ingelogd beschouwd.
  • De gebruiker gebruikte een wachtwoordsleutel, maar heeft een ander apparaat gebruikt dan het apparaat dat hij momenteel gebruikt (door 'een ander apparaat' te selecteren dat in het bovenstaande voorbeeld wordt weergegeven). Dit kan worden bevestigd door het kenmerk AuthenticatorAttachment te inspecteren in het geretourneerde PublicKeyCredential-object .

1.2: Verificatie tussen apparaten

Als de gebruiker een wachtwoordsleutel van een ander apparaat (zoals een telefoon, tablet of FIDO2-beveiligingssleutel) heeft gebruikt, heeft de eigenschap authenticatorAttachment in het verificatieantwoord (getAssertion) de waarde cross-platform.

In dat scenario biedt u de gebruiker de keuze om een wachtwoordsleutel te maken op het lokale apparaat. Dit leidt tot een naadlozere gebruikerservaring in de toekomst, omdat de gebruiker geen ander apparaat hoeft te gebruiken.

Stel een wachtwoordsleutel in op dit apparaat.

1.3: Een opmerking over gebruikersverificatie

Deze richtlijnen stellen userVerification in op preferred, wat betekent dat gebruikersverificatie indien mogelijk wordt geprobeerd.

Sommige apparaten, zoals desktopcomputers en oudere laptops, hebben mogelijk geen biometrische sensoren. Als userVerification op deze apparaten is ingesteld required, wordt de gebruiker mogelijk gevraagd om zijn wachtwoord voor systeemaanmelding in te voeren voor elke aanmelding met een wachtwoordsleutel. En dat kan frustrerend zijn voor hen.

Wanneer preferred wordt gebruikt, zullen sommige platformauthenticators altijd een gebruikersverificatiecontrole vereisen wanneer het apparaat biometrische sensoren heeft, maar kunnen gebruikersverificatie op apparaten zonder biometrische sensoren overslaan.

Het resultaat van de gebruikersverificatie (overgebracht in authenticatorgegevensvlaggen) weerspiegelt het werkelijke verificatieresultaat van de gebruiker en moet altijd worden gevalideerd op basis van uw vereisten op de server.

1.4: De gebruiker aanmelden voor wachtwoordsleutels

Controleer eerst of de gebruiker voldoende sterk is geverifieerd met behulp van andere aanmeldingsmethoden, waaronder meervoudige verificatie.

Zorg er ten tweede voor dat de combinatie van het apparaat en besturingssysteem van de gebruiker ondersteuning biedt voor wachtwoordsleutels door het aanroepen van:

PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()

Als wachtwoordsleutels worden ondersteund, wordt dat geretourneerd true. Als ze niet worden ondersteund, wordt false geretourneerd en moet u het aanmeldingsproces voor de wachtwoordsleutel stopzetten.

Toon een opt-in of upsell venster/scherm of pagina aan de gebruiker die hen de mogelijkheid biedt om een beveiligingssleutel te maken.

Snellere, veiligere aanmelding met wachtwoordsleutels!

Aanbeveling

Om ervoor te zorgen dat de gebruiker volledig geïnformeerde toestemming geeft, kunt u langere beschrijvingen weergeven (of koppelen aan) waarin wordt uitgelegd dat alle gebruikers die het huidige apparaat kunnen ontgrendelen, toegang hebben tot het account bij de relying party (RP).

Als de gebruiker toestemming verleent, roep navigator.credentials.create() samen met de opties uit het onderstaande voorbeeld aan.

navigator.credentials.create({
  publicKey: {
    rp: {
      // User-friendly name of your service.
      name: "Passkeys Developer",
      // Relying party (RP) identifier (hostname/FQDN).
      id: passkeys.contoso"
    },

    user: {
      // Persistent, unique identifier for the user account in your backend.
      id: Uint8Array.from("0525bc79-5a63-4e47-b7d1-597e25f5caba", c => c.charCodeAt(0)),
      // User-friendly identifier often displayed to the user (for example, email address).
      name: "amanda@contoso.com",
      // Human-readable display name, sometimes displayed by the client.
      displayName: "Amanda Brady"
    },
    // The challenge is a buffer of cryptographically random bytes generated on your backend,
    // and should be tightly bound to the current user session.
    challenge: Uint8Array.from("XZJscsUqtBH7ZB90t2g0EbZTZYlbSRK6lq7zlN2lJKuoYMnp7Qo2OLzD7xawL3s", c => c.charCodeAt(0)),
    pubKeyCredParams: [
      // An array of objects describing what public key types are acceptable to a server.
      {
        "type": "public-key",
        "alg": -7 // EC P256
      },
      {
        "type": "public-key",
        "alg": -257 // RSA
      }
    ],
    excludeCredentials: [
      // Array of credential IDs for existing passkeys tied to the user account.
      // This avoids creating a new passkey in an authenticator that already has 
      // a passkey tied to the user account.
      {
        // Example only.
        type: "public-key",
        id: new Uint8Array([21, 31, 56, ...]).buffer
      },
      {
        // Example only.
        type: "public-key",
        id: new Uint8Array([21, 31, 56, ...]).buffer
      }
    ],
    authenticatorSelection: {
      // Tells the authenticator to create a passkey.
      residentKey: "required",
      // Tells the client/authenticator to request user verification where possible;
      // for example, a biometric or a device PIN.
      userVerification: "preferred"
    },
    "extensions": {
      // Returns details about the passkey.
      "credProps": true
    }
  }
})

Opmerking

Het is raadzaam dat de meeste relying parties (RPs) de attestation-overdrachtsparameter attestation niet specificeren (dus standaard ingesteld op geen), of in plaats daarvan expliciet de waarde indirect gebruiken. Dit garandeert de meer gestroomlijnde gebruikerservaring (platformen zullen waarschijnlijk toestemming vragen van de gebruiker voor andere vormen van attestatie-overdracht, wat waarschijnlijk resulteert in een groter deel van mislukte verificaties vanwege gebruikers die de aanmaak annuleren).

Wanneer de WebAuthn-aanroep is afgerond, verstuur het antwoord naar uw server en koppel de geretourneerde openbare sleutel en referentie-ID aan het eerder geverifieerde gebruikersaccount.

Gebruikssituatie 2: Her-authenticatie

Het gebruik van wachtwoordsleutels voor een herauthenticatie kan nodig zijn om een van de volgende redenen:

  • De gebruiker is afgemeld en wil zich nu opnieuw aanmelden.
  • De gebruikerssessie is verlopen vanwege inactiviteit en de gebruiker wil zich opnieuw aanmelden.
  • De gebruiker staat op het punt om een gevoelige actie uit te voeren en moet de controle over de gebruikerssessie opnieuw bevestigen.

Als u de gebruiker in elk van deze situaties opnieuw wilt verifiëren, gebruikt u wachtwoordsleutels die u in de vorige use case hebt ingesteld. De WebAuthn-API-aanroep is in alle drie de gevallen hetzelfde, maar de UI-aanpak die u biedt, is iets anders. Omdat het specifieke account door u is opgegeven, wordt de gebruiker niet gevraagd om een ander account in uw service te selecteren.

2.1: Gevoelige acties

Laten we eerst de gebruikersinterface voor de derde reden bekijken: wanneer het tijd is om opnieuw te verifiëren voor een gevoelige actie, controleert u of u een referentie-id hebt voor ten minste één wachtwoordsleutel voor de gebruiker.

Als er geen dergelijke referentie-id beschikbaar is, kunt u een traditionele aanmeldingsuitdaging aanbieden die geschikt is voor opnieuw verificatie, bijvoorbeeld:

Laten we ervoor zorgen dat u 1 bent

Aanbeveling

Het is raadzaam dat gebruikers op deze aanmeldingsvraagpagina hun account-id niet kunnen wijzigen. De aanmeldingsvraag moet ook iets zijn dat een niet-geautoriseerde gebruiker van het apparaat niet kan doorgeven.

Als u daarentegen ten minste één referentie-id voor de passkey van de gebruiker vindt, kunt u passkeys gebruiken om opnieuw te verifiëren.

Laten we ervoor zorgen dat u 2 bent

Wanneer de gebruiker klaar is (in het bovenstaande voorbeeld, wanneer hij op de knop "Ga" klikt), roep navigator.credentials.get() aan en geef alle toegangssleutel-id's van de gebruiker door:

navigator.credentials.get({
  publicKey: {
    challenge: ...,
    rpId: ...,
     allowCredentials: [{
      type: "public-key",      
      id: new UInt8Array([21, 31, 56, ...]).buffer,
    }, {
      type: "public-key",
      id: new UInt8Array([21, 31, 56, ...]).buffer,
    }, {
      ...
    }],
    // see note below
    userVerification: "preferred", 
  }
});

Opmerking

Lees de richtlijnen voor userVerification uit de vorige use-case.

Als de gebruiker in plaats daarvan op 'Probeer een andere manier' klikt, moet u hen andere aanmeldingsmethoden (wachtwoord, enzovoort) aanbieden om ze opnieuw te verifiëren (ervan uitgaande dat de gebruiker dergelijke andere aanmeldingsmethoden beschikbaar heeft).

2.2: Verlopen sessies en afmelding

Nu gaan we kijken naar de situatie waarin de herauthenticatie opnieuw wordt geactiveerd omdat de gebruiker zich heeft afgemeld of de relying party (RP) de sessie van de gebruiker heeft laten verlopen. Om dit te vergemakkelijken, moet de RP een vorm van gebruikerssessiestatus behouden die hen herinnert aan het account dat voorheen was aangemeld, zelfs wanneer ze de gebruiker afmelden (dat kan worden bereikt met behulp van browserartefacten zoals cookies of lokale opslag).

Opmerking

Een relying party (RP) kan ervoor kiezen om afmelden als een uitgebreide actie te behandelen en dus alle verwijzingen naar de identiteit van de gebruiker te verwijderen. Een dergelijke RP moet een volgende aanmelding behandelen, zoals een accountboottrap, en herhaal de stappen die eerder zijn uitgelegd.

u, als de RP, kunt vervolgens een inlogpagina zoals deze weergeven:

Welkom terug! 1

Als de gebruiker op 'Een ander account gebruiken' klikt, moet u het bootstrapproces voor het account starten, zoals uitgelegd in de vorige use case, waarbij het platform de gebruiker laat kiezen welk account hij/zij wil gebruiken.

Opmerking

In dat geval moet u de gebruiker ook de mogelijkheid geven om het voorgestelde account volledig te verwijderen uit de lijst op de aanmeldingspagina.

Maar als de gebruiker op de knop Aanmelden als klikt, controleert u of er ten minste één wachtwoordsleutelreferentie-id aan de gebruiker is gekoppeld. Als er geen referentie-ID beschikbaar is, dient u een traditionele login-uitdaging aan die geschikt is voor herauthenticatie, bijvoorbeeld:

Welkom terug! 2

Als u daarentegen ten minste één referentie-id voor de passkey van de gebruiker vindt, kunt u passkeys gebruiken om opnieuw te verifiëren.

Welkom terug! 3

Wanneer de gebruiker klaar is (in het bovenstaande voorbeeld, wanneer hij op de knop "Ga" klikt), roep navigator.credentials.get() aan, precies zoals al wordt weergegeven (dat wil zeggen door alle ID's van wachtwoordsleutelreferenties van de gebruiker door te geven).

Als de gebruiker in plaats daarvan op 'Probeer een andere manier' klikt, moet u hen andere aanmeldingsmethoden (wachtwoord, enzovoort) aanbieden om ze opnieuw te verifiëren (ervan uitgaande dat de gebruiker dergelijke andere aanmeldingsmethoden beschikbaar heeft).

Volgende stappen

Zie vervolgens Hulpprogramma's en bibliotheken voor wachtwoordsleutels.

Meer informatie