Jak stworzyliśmy kartę WebAuthn w Chrome DevTools

Fawaz Mohammad
Fawaz Mohammad
Nina Satragno
Nina Satragno

Interfejs Web Uwierzytelnianie API (nazywany również WebAuthn) pozwala serwerom na rejestrowanie i uwierzytelnianie użytkowników za pomocą kryptografii klucza publicznego zamiast haseł. Jest to możliwe dzięki włączeniu integracji między tymi serwerami i mechanizmami uwierzytelniania. Mogą to być specjalne urządzenia fizyczne (np. klucze bezpieczeństwa) lub zintegrowane z platformami (np. czytniki linii papilarnych). Więcej informacji o WebAuthn znajdziesz na stronie webauthn.guide.

Problemy deweloperów

Przed tym projektem WebAuthn nie było obsługiwane przez natywne debugowanie w Chrome. Deweloper tworzący aplikację korzystającą z WebAuth, musiał mieć dostęp do fizycznych uwierzytelniania. Było to szczególnie trudne z dwóch powodów:

  1. Istnieje wiele różnych rodzajów uwierzytelniania. Debugowanie szerokiego zakresu konfiguracji i możliwości wymagało, aby deweloper miał dostęp do wielu różnych, czasem kosztownych aplikacji uwierzytelniających.

  2. Fizyczne aplikacje uwierzytelniające są z założenia bezpieczne. W związku z tym sprawdzenie ich stanu jest zwykle niemożliwe.

Chcieliśmy to ułatwić, dodając obsługę debugowania bezpośrednio w Narzędziach deweloperskich w Chrome.

Rozwiązanie: nowa karta WebAuthn

Karta WebAuthn DevTools ułatwia debugowanie WebAuthn, umożliwiając programistom emulowanie tych uwierzytelniania, dostosowywanie ich możliwości i sprawdzanie stanów.

Nowa karta WebAuthn

Implementacja

Dodanie obsługi debugowania do aplikacji WebAuthn składało się z 2-częściowego procesu.

Proces dwuczęściowy

Część 1. Dodawanie domeny WebAuthn do protokołu Chrome DevTools

Najpierw wdrożyliśmy nową domenę w protokole Chrome DevTools Protocol (CDP), który łączy się z modułem obsługi komunikującym się z backendem WebAuthn.

CDP łączy interfejs Narzędzi deweloperskich z Chromium. W naszym przypadku użyliśmy działań domeny WebAuthn do przejścia między kartą WebAuthn DevTools a implementacją WebAuthn w Chromium.

Domena WebAuthn umożliwia włączanie i wyłączanie środowiska Virtual Authenticator, które odłącza przeglądarkę od prawdziwego mechanizmu Authenticator i zamiast tego podłącza wirtualne wykrywanie.

Udostępniamy też w domenie metody, które działają jak cienka warstwa, do istniejących interfejsów Virtual Authenticator i Virtual Discovery, które są częścią implementacji WebAuthn w Chromium. Te metody obejmują dodawanie i usuwanie uwierzytelniania, a także tworzenie, pobieranie i usuwanie zarejestrowanych danych logowania.

(Przeczytaj kod)

Część 2. Tworzenie karty widocznej dla użytkownika

Następnie w interfejsie Narzędzi deweloperskich stworzyliśmy kartę dla użytkownika. Karta składa się z widoku i modelu. Automatycznie wygenerowany agent łączy domenę z kartą.

Chociaż potrzebne są 3 niezbędne komponenty, zastanawialiśmy się tylko nad 2 z nich: model i model. Trzeci komponent, agent, jest generowany automatycznie po dodaniu domeny. W skrócie: agent to warstwa, która przenosi wywołania między interfejsem a platformą CDP.

Model

Model to warstwa JavaScript, która łączy agenta z widokiem danych. W naszym przypadku model jest dość prosty. Pobiera polecenia z widoku, buduje żądania w taki sposób, aby zostały wykorzystane przez CDP, a następnie wysyła je przez agenta. Żądania te są zazwyczaj wysyłane w jedną stronę i nie są wysyłane z powrotem do widoku.

Czasami jednak zwracamy odpowiedź z modelu, aby podać identyfikator nowo utworzonego mechanizmu uwierzytelniania lub zwrócić dane logowania zapisane w istniejącym narzędziu.

(Przeczytaj kod)

Widok

Nowa karta WebAuthn

Wykorzystujemy go, aby udostępnić interfejs użytkownika, który deweloper może znaleźć, uzyskując dostęp do Narzędzi deweloperskich. Zawiera ona:

  1. Pasek narzędzi włączający środowisko wirtualnego mechanizmu uwierzytelniającego.
  2. Sekcja do dodawania uwierzytelniania.
  3. Sekcja tworzonych uwierzytelniania.

(Przeczytaj kod)

Pasek narzędzi włączający środowisko wirtualnego mechanizmu uwierzytelniającego

pasek narzędzi

Ponieważ większość interakcji użytkowników odbywa się jednocześnie z jednym narzędziem uwierzytelniającym, a nie z całą kartą, jedyną dostępną funkcją na pasku narzędzi jest włączanie i wyłączanie środowiska wirtualnego.

Dlaczego jest to konieczne? Użytkownik musi samodzielnie przełączyć środowisko, bo spowoduje to odłączenie przeglądarki od prawdziwego mechanizmu aplikacji Authenticator. Dlatego gdy to ustawienie jest włączone, połączone fizyczne uwierzytelnianie, takie jak czytnik linii papilarnych, nie będzie rozpoznawane.

Uznaliśmy, że taki przełącznik zapewnia większy komfort użytkownikom, zwłaszcza tym, którzy korzystają z karty WebAuthn w celu wyłączenia prawdziwego wykrywania.

Dodawanie sekcji Authenticator

Dodawanie sekcji Authenticator

Po włączeniu środowiska wirtualnego uwierzytelniania deweloper otrzymuje wbudowany formularz, który umożliwia dodanie wirtualnego uwierzytelniania. W tym formularzu znajdują się opcje dostosowywania, które pozwalają użytkownikowi wybrać protokół i metody przesyłania uwierzytelniania, a także to, czy obsługuje on klucze rezydentne i weryfikację użytkownika.

Gdy użytkownik kliknie Dodaj, te opcje są grupowane i wysyłane do modelu, który wywołuje uwierzytelnianie. Po zakończeniu interfejs otrzyma odpowiedź i zmodyfikuje interfejs tak, aby zawierał nowo utworzony mechanizm uwierzytelniający.

Widok aplikacji Authenticator

Widok aplikacji Authenticator

Za każdym razem, gdy jest emulowana aplikacja uwierzytelniająca, do widoku tego modułu umieszczamy sekcję, która będzie reprezentować ten moduł. Każda sekcja uwierzytelniania zawiera nazwę, identyfikator, opcje konfiguracji, przyciski do usuwania lub aktywowania modułu uwierzytelniającego, oraz tabelę danych logowania.

Nazwa aplikacji Authenticator

Nazwę uwierzytelniania można dostosować. Domyślnie jest to „Authenticator” połączone z 5 ostatnimi znakami identyfikatora. Początkowo nazwa uwierzytelniania to pełny identyfikator i nie można go zmienić. Wprowadziliśmy niestandardowe nazwy, aby użytkownik mógł oznaczyć mechanizm uwierzytelniający zgodnie z jego możliwościami, fizycznym emulacją aplikacji lub pseudonimem, który jest łatwiejszy do zrozumienia niż 36-znakowy identyfikator.

Tabela danych logowania

Do każdej sekcji narzędzia uwierzytelniającego dodaliśmy tabelę, która zawiera wszystkie dane logowania zarejestrowane przez ten moduł. W każdym wierszu znajdują się informacje o danych logowania oraz przyciski umożliwiające ich usunięcie lub wyeksportowanie.

Obecnie informacje potrzebne do wypełnienia tych tabel zbieramy, przeprowadzając odpytywanie CDP w celu uzyskania zarejestrowanych danych uwierzytelniających dla każdego uwierzytelniania. W przyszłości planujemy dodać zdarzenie tworzenia danych logowania.

Przycisk Aktywne

Do każdej sekcji uwierzytelniania dodaliśmy przycisk Aktywna. Obecnie ustawiony jako aktywny mechanizm uwierzytelniający będzie jedynym, który nasłuchuje i zarejestruje dane logowania. Bez tego rejestracja danych uwierzytelniających z wykorzystaniem wielu uwierzytelniania nie jest deterministyczne, a to byłby poważny błąd przy próbie przetestowania WebAuthn w ich przypadku.

Stan aktywności wdrożyliśmy w wirtualnych uwierzytelnianiech przy użyciu metody SetUserPresence. Metoda SetUserPresence określa, czy testy obecności użytkownika zakończyły się powodzeniem w przypadku danego mechanizmu uwierzytelniającego. Jeśli go wyłączymy, aplikacja uwierzytelniająca nie będzie mogła nasłuchiwać danych logowania. Dzięki temu, że upewniając się, że jest on włączony dla co najmniej 1 mechanizmu uwierzytelniającego (ten ustawiony jako aktywny), i wyłączając obecność użytkowników w przypadku wszystkich innych, możemy wymusić działanie deterministyczne.

Ciekawym wyzwaniem, z którym natknęliśmy się podczas dodawania aktywnego przycisku, było unikanie warunku wyścigu. Rozważ taki scenariusz:

  1. Użytkownik klika opcję Aktywny w aplikacji Authenticator X, wysyłając do CDP prośbę o ustawienie X jako aktywnego. Opcja Aktywna obok X jest zaznaczona, a pozostałe odznaczone.

  2. Bezpośrednio potem użytkownik klika opcję Aktywna dla aplikacji Authenticator Y, wysyłając do CDP żądanie ustawienia Y jako aktywnego. Opcja Aktywna obok Y jest zaznaczona, a wszystkie pozostałe, w tym opcja X, są odznaczone.

  3. W backendzie wywołanie ustawienia Y jako aktywnej zostało ukończone i zakończone. Y jest teraz aktywny, a pozostałe uwierzytelnianie nie jest.

  4. W backendzie wywołanie ustawienia X jako aktywnego zostało ukończone i zakończone. X jest teraz aktywne, a pozostałe uwierzytelnianie, w tym Y, jest nieaktywne.

Sytuacja wygląda tak: X jest aktywnym narzędziem uwierzytelniającym. Jednak opcja Aktywna obok X nie jest wybrana. To nie jest aktywnym narzędziem uwierzytelniającym. Jednak opcja Aktywna obok Y jest wybrana. Istnieje niezgodność między interfejsem a rzeczywistym stanem uwierzytelniania. Oczywiście stanowi to problem.

Nasze rozwiązanie: wyznacz pseudodwukierunkową komunikację między przyciskami a aktywnym narzędziem uwierzytelniającym. Po pierwsze, zachowujemy w widoku zmienną activeId, aby śledzić identyfikator obecnie aktywnego narzędzia uwierzytelniającego. Następnie czekamy na wywołanie ustawienia aktywnego uwierzytelniania i zwracamy tym samym funkcję activeId na jego identyfikator. Na koniec przeanalizujemy każdą sekcję uwierzytelniania. Jeśli identyfikator tej sekcji ma wartość activeId, ustawiamy przycisk na wybrany. W przeciwnym razie przycisk jest odznaczony.

Jak to wygląda:


 async _setActiveAuthenticator(authenticatorId) {
   await this._clearActiveAuthenticator();
   await this._model.setAutomaticPresenceSimulation(authenticatorId, true);
   this._activeId = authenticatorId;
   this._updateActiveButtons();
 }
 
 _updateActiveButtons() {
   const authenticators = this._authenticatorsView.getElementsByClassName('authenticator-section');
   Array.from(authenticators).forEach(authenticator => {
     authenticator.querySelector('input.dt-radio-button').checked =
         authenticator.getAttribute('data-authenticator-id') === this._activeId;
   });
 }
 
 async _clearActiveAuthenticator() {
   if (this._activeId) {
     await this._model.setAutomaticPresenceSimulation(this._activeId, false);
   }
   this._activeId = null;
 }

Dane na temat wykorzystania

Chcieliśmy śledzić użycie tej funkcji. Na początku dostępne były 2 opcje.

  1. Licz każde otwarcie karty WebAuthn w Narzędziach deweloperskich. Ta opcja może prowadzić do zawyżenia liczby wyświetleń, ponieważ ktoś może otworzyć kartę, nie używając jej.

  2. Możesz śledzić, ile razy zostało włączone pole wyboru „Włącz środowisko wirtualnego uwierzytelniania” na pasku narzędzi. Wiąże się to również z ryzykiem zawyżenia liczby wyświetleń, ponieważ niektóre z nich mogły wielokrotnie włączać i wyłączać środowisko w ramach tej samej sesji.

Ostatecznie zdecydowaliśmy się wybrać to drugie rozwiązanie, ale ograniczyć zliczanie – w tym celu sprawdź, czy środowisko nie zostało już włączone podczas sesji. Dlatego zwiększamy liczbę tylko o 1 niezależnie od tego, ile razy deweloper przełączył środowisko. Jest to możliwe, ponieważ przy każdym ponownym otwarciu karty tworzona jest nowa sesja, co pozwala zresetować sprawdzanie i umożliwiać ponowne zwiększenie wartości.

Podsumowanie

Dziękujemy za przeczytanie tekstu. Jeśli masz jakieś sugestie dotyczące ulepszenia karty WebAuthn, daj nam znać, przesyłając błąd.

Jeśli chcesz dowiedzieć się więcej o WebAuthn, skorzystaj z poniższych materiałów:

Pobieranie kanałów podglądu

Jako domyślnej przeglądarki programistycznej możesz użyć Chrome Canary, Dev lub Beta. Te kanały podglądu dają dostęp do najnowszych funkcji Narzędzi deweloperskich, testują nowoczesne interfejsy API platform internetowych oraz wykrywają problemy w witrynie, zanim zrobią to użytkownicy.

Kontakt z zespołem Narzędzi deweloperskich w Chrome

Użyj tych opcji, aby omówić nowe funkcje i zmiany w poście lub wszelkich innych sprawach związanych z Narzędziami dla programistów.

  • Sugestię lub opinię możesz przesłać na stronie crbug.com.
  • Aby zgłosić problem z Narzędziami deweloperskimi, kliknij Więcej opcji   Więcej   > Pomoc > Zgłoś problemy z Narzędziami deweloperskimi.
  • zatweetować na @ChromeDevTools.
  • Komentarze do filmów o narzędziach dla deweloperów w YouTube lub filmach w YouTube ze wskazówkami dotyczącymi Narzędzi deweloperskich.