Udostępnij przez


Przypadki użycia kluczy dostępu (cyfrowych)

W tym temacie opisano niektóre przypadki użycia kluczy dostępu.

Przypadek użycia 1: Bootstrapping

Uruchamianie konta w Internecie.

1.1: Uwierzytelnianie użytkownika

Ta sekcja ma zastosowanie, gdy jednostka uzależniona (RP) nie wie jeszcze, kto kontroluje urządzenie klienckie. Nie ma artefaktu przeglądarki dostępnego dla strony trzeciej (takiej jak plik cookie lub identyfikator uwierzytelnienia w pamięci lokalnej), chociaż obecnie zakładamy, że użytkownik ma obecnie istniejące konto u strony trzeciej.

Aby uruchomić konto, zaserwuj użytkownikowi stronę logowania.

Zacznij od monitowania użytkownika o identyfikator konta; zazwyczaj nazwa użytkownika lub adres e-mail.

Rejestrowanie

Aby obsługiwać interfejs użytkownika automatycznego wypełniania dla kluczy dostępu, upewnij się, że:

  1. Dodaj wartość username i webauthn do wszystkich istniejących adnotacji autouzupełniania w polu wprowadzania nazwy użytkownika.
<div>
  <label for="username">Username:</label>
  <input name="username" id="loginform.username"
         autocomplete="username webauthn">
</div>
  1. Podczas ładowania strony użyj instrukcji if, aby sprawdzić, czy interfejs użytkownika automatycznego wypełniania (mediacja warunkowa) jest dostępny, a następnie wywołaj navigator.credentials.get() z mediation: "conditional" i 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>

Powyższe czynności spowodują, że wystąpią następujące zdarzenia:

  • Pobierz opcje uwierzytelniania z serwera. Zwróć co najmniej losowe challenge i rpId, aby zostały skojarzone z tym żądaniem uwierzytelniania.
  • Gdy użytkownik wchodzi w interakcję z polem nazwy użytkownika, przeglądarka i platforma będą sprawdzać, czy istnieje klucz bezpieczeństwa (w uwierzytelniającym elemencie platformy), który może być używany ze zaufaną stroną.
  • W takim przypadku klucz dostępu zostanie wyświetlony użytkownikowi jako opcja wyboru (wraz z innymi poświadczeniami, które mogą być wypełniane automatycznie, takie jak nazwy użytkowników przechowywane w menedżerze haseł przeglądarki). Przeglądarka/platforma może renderować interfejs użytkownika podobny do przedstawionego poniżej. Mimo że dokładny wygląd i działanie różnią się między różnymi platformami i formatami.

Logowanie przy użyciu klucza dostępu

  • Jeśli użytkownik wybierze klucz dostępu, interfejs użytkownika platformy poprowadzi go przez etap weryfikacji tożsamości użytkownika, który często opiera się na danych biometrycznych.
  • Jeśli użytkownik pomyślnie przejdzie weryfikację użytkownika, navigator.credentials.get() wywołanie zakończy się pomyślnie i zwróci odpowiedź webAuthn.
  • Jeśli użytkownik wybierze poświadczenia inne niż klucz dostępu, przeglądarka/platforma wybierze inną odpowiednią akcję (taką jak automatyczne wypełnianie nazwy użytkownika), a navigator.credentials.get() wywołanie nie zostanie rozwiązane.
  • Jeśli użytkownik wybierze opcję "Klucz dostępu z innego urządzenia" (dokładny tekst będzie się nieznacznie różnić w zależności od platformy), przeglądarka/platforma przeprowadzi użytkownika za pomocą klucza zabezpieczeń FIDO2 lub przepływu uwierzytelniania między urządzeniami (CDA) w celu użycia klucza dostępu ze swojego smartfona lub tabletu w celu dostarczenia odpowiedzi WebAuthn na navigator.credentials.get() połączenie.
  • Wyślij odpowiedź webAuthn na serwer w celu weryfikacji i dodatkowych kontroli zabezpieczeń. Jeśli wszystkie testy kończą się powodzeniem, rozpocznij sesję uwierzytelnioną dla tego użytkownika.

Dlatego jest to nazywane warunkowym interfejsem użytkownika (lub najczęściej trybem automatycznego wypełniania interfejsu użytkownika) protokołu WebAuthn — interfejs użytkownika platformy uwierzytelniania, który prowadzi użytkownika przez weryfikację lub przez użycie ich telefonu, jest wyświetlany tylko wtedy, gdy użytkownik ma klucz dostępu na tym urządzeniu (lub wybiera opcję "innego urządzenia").

Jak widać, w tym trybie wywołanie navigator.credentials.get() albo się powiedzie, albo nie, ponieważ nigdy się nie zakończy. Jeśli to się powiedzie, wynik wywołania spowoduje wyświetlenie zarówno identyfikatora użytkownika, jak i podpisanej asercji WebAuthn, która będzie używana przez jednostkę uzależnioną (RP) do uwierzytelniania użytkownika.

Jeśli wywołanie nie powiedzie się, należy przeprowadzić starsze uwierzytelnianie użytkownika. Uzyskasz nazwę użytkownika z tej pierwszej strony, a następnie na kolejnych stronach będziesz obsługiwać odpowiednie kolejne wyzwania związane z logowaniem (takie jak hasła, reagowanie na wyzwania związane z wiadomościami SMS itp.) dla użytkownika. Mogą one obejmować kroki odzyskiwania konta w przypadku, gdy użytkownik zapomniał hasła lub nie może przejść regularnych wyzwań związanych z logowaniem. Gdy użytkownik przejdzie wszystkie wyzwania związane z logowaniem, zostanie uznany za uwierzytelniony i zalogowany.

Jeśli użytkownik nie ma jeszcze konta u zaufanej strony (RP), zazwyczaj na stronie logowania należy dać użytkownikowi możliwość założenia konta. Jeśli użytkownik wybierze tę opcję, zbierzesz niezbędne informacje, aby otworzyć nowe konto. Jeśli pomyślnie otworzy nowe konto, zostanie również uznane za uwierzytelnione i zalogowane.

Po zalogowaniu użytkownika może upłynął czas na skonfigurowanie nowego klucza dostępu. Wykonaj to w przypadku dowolnego z następujących przypadków:

  • Użytkownik uruchomił swoje konto na urządzeniu, przekazując wyzwania związane z logowaniem bez klucza dostępu (np. przy użyciu hasła).
  • Użytkownik właśnie utworzył nowe konto na stronie polegającej (RP) i jest uważany za zalogowanego z tego powodu.
  • Użytkownik używał klucza dostępu, ale używał innego urządzenia niż aktualnie używane (wybierając pozycję "inne urządzenie" pokazane w powyższym przykładzie). Można to potwierdzić, sprawdzając atrybut authenticatorAttachment w zwróconym obiekcie PublicKeyCredential .

1.2: Uwierzytelnianie między urządzeniami

Jeśli użytkownik użył klucza dostępu z innego urządzenia (takiego jak telefon, tablet lub klucz zabezpieczeń FIDO2), właściwość authenticatorAttachment w odpowiedzi uwierzytelniania (getAssertion) będzie miała wartość cross-platform.

W tym scenariuszu użytkownik może utworzyć klucz dostępu na swoim urządzeniu lokalnym. Spowoduje to bardziej bezproblemowe środowisko użytkownika w przyszłości, ponieważ użytkownik nie będzie musiał korzystać z innego urządzenia.

Skonfiguruj klucz dostępu na tym urządzeniu!

1.3: Uwaga dotycząca weryfikacji użytkownika

Te wskazówki ustawiają wartość userVerification na preferred, co oznacza, że weryfikacja użytkownika zostanie podjęta w miarę możliwości.

Niektóre urządzenia, takie jak komputery stacjonarne i starsze laptopy, mogą nie mieć czujników biometrycznych. Na tych urządzeniach, jeśli userVerification jest ustawione na required, użytkownik może zostać poproszony o wprowadzenie hasła logowania do systemu przy każdym logowaniu przy użyciu klucza dostępu. I to może być frustrujące dla nich.

Jeśli preferred jest używany, niektórzy autoryzatorzy platformy zawsze będą wymagać weryfikacji użytkownika, gdy urządzenie ma czujniki biometryczne, ale mogą pominąć weryfikację na urządzeniach bez tych czujników.

Wynik weryfikacji użytkownika (przekazany w flagach danych wystawcy uwierzytelniania) odzwierciedla rzeczywisty wynik weryfikacji użytkownika i powinien być zawsze weryfikowany pod kątem wymagań na serwerze.

1.4: Włącz użytkownika do kluczy dostępu

Najpierw sprawdź, czy użytkownik jest wystarczająco mocno uwierzytelniony przy użyciu innych metod logowania, w tym uwierzytelniania wieloskładnikowego.

Po drugie upewnij się, że kombi urządzenia użytkownika i systemu operacyjnego obsługują klucz dostępu, wywołując następujące wywołanie:

PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()

Jeśli są obsługiwane kluczami dostępu, funkcja zwróci wartość true. Jeśli nie są one obsługiwane, zostanie zwrócony false, i trzeba przerwać proces rejestracji klucza dostępu.

Udostępniaj użytkownikowi opcję lub "upsell" modal/interstitial lub stronę oferującą użytkownikowi możliwość utworzenia klucza dostępu:

Szybsze, bezpieczniejsze logowanie za pomocą kluczy dostępu!

Wskazówka

Aby upewnić się, że użytkownik udziela w pełni świadomej zgody, rozważ wyświetlenie (lub udostępnienie) dłuższych opisów wyjaśniających, że wszyscy użytkownicy, którzy mogą odblokować bieżące urządzenie, mogą uzyskać dostęp do konta w stronie polegającej (RP).

Jeśli użytkownik wyrazi zgodę, wywołaj metodę navigator.credentials.create() z opcjami pokazanymi w poniższym przykładzie:

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

Uwaga / Notatka

Zalecamy, aby większość podmiotów polegających (RPs) nie określała parametru przesyłania zaświadczenia attestation (co domyślnie skutkuje brakiem wartości), lub jawnie używała wartości indirect. Gwarantuje to najbardziej płynne doświadczenie użytkownika (platformy mogą uzyskać zgodę użytkownika na inne rodzaje przekazywania zaświadczeń, co prawdopodobnie prowadzi do większego odsetka nieudanych prób tworzenia poświadczeń, ponieważ użytkownicy anulują proces).

Gdy wywołanie WebAuthn rozwiąże problem, wyślij odpowiedź na serwer i skojarz zwrócony klucz publiczny i identyfikator poświadczeń z wcześniej uwierzytelnionym kontem użytkownika.

Przypadek użycia 2: Ponowne uwierzytelnianie

Używanie kluczy dostępu do ponownego uwierzytelniania może być konieczne z dowolnego z następujących powodów:

  • Użytkownik wylogował się, a teraz chce się zalogować ponownie.
  • Sesja użytkownika wygasła z powodu braku aktywności, a użytkownik chce się zalogować ponownie.
  • Użytkownik ma wykonać akcję wrażliwą i musi ponownie potwierdzić kontrolę nad sesją użytkownika.

Aby ponownie uwierzytelnić użytkownika w każdej z tych sytuacji, użyjesz kluczy dostępu skonfigurowanych w poprzednim przypadku użycia. Wywołanie interfejsu API WebAuthn jest takie samo we wszystkich trzech przypadkach, ale sposób obsługi interfejsu użytkownika jest nieco inny. Ponieważ określone konto jest określone przez Ciebie, platforma nie będzie monitować użytkownika o wybranie innego konta w usłudze.

2.1: Działania wrażliwe

Najpierw przyjrzyjmy się interfejsowi użytkownika z trzeciego powodu — gdy nadszedł czas na ponowne uwierzytelnienie dla akcji poufnej, sprawdź, czy masz identyfikator poświadczeń dla co najmniej jednego klucza dostępu dla użytkownika.

Jeśli taki identyfikator poświadczeń nie jest dostępny, należy podjąć tradycyjne kroki związane z logowaniem odpowiednie do ponownego uwierzytelnienia, na przykład:

Upewnijmy się, że to ty 1

Wskazówka

Zalecamy, aby na tej stronie wyzwania logowania użytkownicy nie mogli zmienić identyfikatora konta. Ponadto wyzwanie logowania powinno być czymś, czego nie może przejść nieautoryzowany użytkownik urządzenia.

Jeśli znajdziesz co najmniej jeden identyfikator poświadczenia klucza dostępu dla użytkownika, możesz użyć kluczy dostępu do ponownego uwierzytelniania.

Upewnijmy się, że to Ty 2

Gdy użytkownik jest gotowy (w powyższym przykładzie po kliknięciu przycisku "Przejdź" wywołaj metodę navigator.credentials.get(), przekazując wszystkie identyfikatory poświadczeń klucza dostępu użytkownika:

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

Uwaga / Notatka

Zapoznaj się ze wskazówkami dotyczącymi weryfikacji użytkownika z poprzedniego przypadku użycia.

Jeśli użytkownik zamiast tego kliknie pozycję "Wypróbuj inny sposób", należy zaoferować im inne metody logowania (hasło itp.), aby je ponownie uwierzytelnić (przy założeniu, że użytkownik ma takie inne dostępne metody logowania).

2.2: Wygasłe sesje i wylogowanie

Teraz zbadamy przypadek, gdy ponowne uwierzytelnianie jest wyzwalane, ponieważ użytkownik się wylogował lub strona docelowa zakończyła sesję użytkownika. Aby to ułatwić, RP musiałby zachować jakąś formę stanu sesji użytkownika przypominającą im konto, które zostało wcześniej zalogowane, nawet gdy uzna użytkownika za wylogowanego (co można osiągnąć przy użyciu mechanizmów przeglądarki, takich jak pliki cookie lub magazyn lokalny).

Uwaga / Notatka

Jednostka uzależniona (RP) może traktować wylogowanie się jako kompleksową akcję, a tym samym usunąć wszystkie odwołania do tożsamości użytkownika. Taka strona żądania powinna traktować następne logowanie jak inicjalizację konta i powtórzyć wcześniej opisane kroki.

Użytkownik, jako dostawca usługi, może następnie obsługiwać stronę logowania podobną do następującej:

Witamy ponownie! 1

Jeśli użytkownik kliknie pozycję "Użyj innego konta", wprowadź przepływ uruchamiania konta — zgodnie z wyjaśnieniem poprzedniego przypadku użycia — powtarzając tam kroki, w których platforma pozwoli użytkownikowi wybrać konto, którego chcesz użyć.

Uwaga / Notatka

W takim przypadku należy również przyznać użytkownikowi możliwość całkowitego usunięcia sugerowanego konta z listy na stronie logowania.

Jeśli jednak użytkownik kliknie przycisk "Zaloguj się jako", sprawdź, czy masz co najmniej jeden identyfikator poświadczeń klucza dostępu skojarzony z użytkownikiem. Jeśli identyfikator poświadczeń nie jest dostępny, należy zastosować tradycyjne wyzwanie związane z logowaniem odpowiednie do ponownego uwierzytelnienia, na przykład:

Witamy ponownie! 2

Jeśli znajdziesz co najmniej jeden identyfikator poświadczenia klucza dostępu dla użytkownika, możesz użyć kluczy dostępu do ponownego uwierzytelniania.

Witamy ponownie! 3

Gdy użytkownik jest gotowy (w powyższym przykładzie po kliknięciu przycisku "Dalej"), wywołaj navigator.credentials.get(), dokładnie tak jak już pokazano (czyli przekazując wszystkie identyfikatory poświadczeń klucza dostępu użytkownika).

Jeśli użytkownik zamiast tego kliknie pozycję "Wypróbuj inny sposób", należy zaoferować im inne metody logowania (hasło itp.), aby je ponownie uwierzytelnić (przy założeniu, że użytkownik ma takie inne dostępne metody logowania).

Dalsze kroki

Następnie zapoznaj się z Narzędzia i biblioteki dla kluczy dostępu.

Dalsze informacje