Hoe we het Chrome DevTools WebAuthn-tabblad hebben gebouwd

Fawaz Mohammed
Fawaz Mohammad
Nina Satragno
Nina Satragno

Met de Web Authentication API , ook bekend als WebAuthn , kunnen servers cryptografie met openbare sleutels gebruiken - in plaats van wachtwoorden - om gebruikers te registreren en te authenticeren. Het doet dit door integratie tussen deze servers en sterke authenticators mogelijk te maken. Deze authenticatoren kunnen speciale fysieke apparaten zijn (bijvoorbeeld beveiligingssleutels) of geïntegreerd zijn met platforms (bijvoorbeeld vingerafdruklezers). U kunt hier meer lezen over WebAuthn op webauthn.guide .

Pijnpunten van ontwikkelaars

Voorafgaand aan dit project ontbrak het WebAuthn aan native foutopsporingsondersteuning in Chrome. Een ontwikkelaar die een app bouwde die WebAuth gebruikte, had toegang tot fysieke authenticators nodig. Dit was vooral moeilijk om twee redenen:

  1. Er zijn veel verschillende smaken authenticatoren. Het debuggen van de breedte van configuraties en mogelijkheden maakte het noodzakelijk dat de ontwikkelaar toegang had tot veel verschillende, soms dure, authenticators.

  2. Fysieke authenticatiemiddelen zijn door hun ontwerp veilig. Daarom is het meestal onmogelijk om hun staat te inspecteren.

We wilden dit eenvoudiger maken door ondersteuning voor foutopsporing rechtstreeks in Chrome DevTools toe te voegen.

Oplossing: een nieuw WebAuthn-tabblad

Het tabblad WebAuthn DevTools maakt het debuggen van WebAuthn veel eenvoudiger doordat ontwikkelaars deze authenticators kunnen emuleren, hun mogelijkheden kunnen aanpassen en hun status kunnen inspecteren.

Nieuw WebAuthn-tabblad

Uitvoering

Het toevoegen van ondersteuning voor foutopsporing aan WebAuthn bestond uit twee delen.

Tweeledig proces

Deel 1: WebAuthn-domein toevoegen aan het Chrome DevTools-protocol

Eerst hebben we een nieuw domein geïmplementeerd in het Chrome DevTools Protocol (CDP) dat inhaakt op een handler die communiceert met de WebAuthn-backend.

Het CDP verbindt de front-end van DevTools met Chromium. In ons geval hebben we de WebAuthn-domeinhandelingen gebruikt om een ​​brug te slaan tussen het tabblad WebAuthn DevTools en Chromium's implementatie van WebAuthn.

Het WebAuthn-domein maakt het in- en uitschakelen van de Virtual Authenticator Environment mogelijk, waardoor de browser wordt losgekoppeld van de echte Authenticator Discovery en in plaats daarvan een Virtual Discovery wordt aangesloten.

We leggen ook methoden in het domein bloot die fungeren als een dunne laag voor de bestaande Virtual Authenticator- en Virtual Discovery-interfaces, die deel uitmaken van de WebAuthn-implementatie van Chromium. Deze methoden omvatten het toevoegen en verwijderen van authenticators, evenals het aanmaken, verkrijgen en wissen van hun geregistreerde inloggegevens.

(Lees de code )

Deel 2: Het bouwen van het gebruikersgerichte tabblad

Ten tweede hebben we een gebruikersgericht tabblad in de DevTools frontend gebouwd. Het tabblad bestaat uit een aanzicht en een model. Een automatisch gegenereerde agent verbindt het domein met het tabblad.

Hoewel er drie noodzakelijke componenten nodig zijn, hoefden we ons slechts zorgen te maken over twee daarvan: het model en de weergave . Het derde onderdeel, de agent , wordt automatisch gegenereerd na het toevoegen van het domein. Kort gezegd is de agent de laag die de oproepen tussen de front-end en het CDP overdraagt.

Het model

Het model is de JavaScript-laag die de agent en de weergave verbindt. Voor ons geval is het model vrij eenvoudig. Het neemt opdrachten uit de weergave, bouwt de verzoeken zo op dat ze door de CDP kunnen worden gebruikt en stuurt ze vervolgens door via de agent. Deze verzoeken zijn meestal eenrichtingsverkeer, waarbij er geen informatie wordt teruggestuurd naar de weergave.

Soms sturen we echter een reactie van het model terug om een ​​ID op te geven voor een nieuw gemaakte authenticator of om de inloggegevens terug te geven die zijn opgeslagen in een bestaande authenticator.

(Lees de code )

Het uitzicht

Nieuw WebAuthn-tabblad

We gebruiken de weergave om de gebruikersinterface te bieden die een ontwikkelaar kan vinden bij toegang tot DevTools. Het bevat:

  1. Een werkbalk om een ​​virtuele authenticatoromgeving in te schakelen.
  2. Een sectie om authenticators toe te voegen.
  3. Een sectie voor gemaakte authenticators.

(Lees de code )

Werkbalk om virtuele authenticatoromgeving in te schakelen

werkbalk

Omdat de meeste gebruikersinteracties met één authenticator tegelijk plaatsvinden in plaats van met het hele tabblad, is de enige functionaliteit die we in de werkbalk bieden het in- en uitschakelen van de virtuele omgeving.

Waarom is dit nodig? Het is belangrijk dat de gebruiker expliciet van omgeving moet wisselen, omdat hierdoor de browser wordt losgekoppeld van de echte Authenticator Discovery. Daarom worden aangesloten fysieke authenticatoren, zoals een vingerafdruklezer, niet herkend als deze is ingeschakeld.

We hebben besloten dat een expliciete schakelaar een betere gebruikerservaring betekent, vooral voor degenen die naar het WebAuthn-tabblad gaan zonder te verwachten dat echte ontdekking wordt uitgeschakeld.

Het toevoegen van de sectie Authenticators

Het toevoegen van de sectie Authenticators

Bij het inschakelen van de virtuele authenticatoromgeving presenteren we de ontwikkelaar een inline-formulier waarmee hij of zij een virtuele authenticator kan toevoegen. Binnen dit formulier bieden we aanpassingsopties waarmee de gebruiker het protocol en de transportmethoden van de authenticator kan bepalen, en ook of de authenticator residente sleutels en gebruikersverificatie ondersteunt.

Zodra de gebruiker op Toevoegen klikt, worden deze opties gebundeld en verzonden naar het model dat de oproep doet om een ​​authenticator te maken. Zodra dat is voltooid, ontvangt de front-end een antwoord en wordt vervolgens de gebruikersinterface aangepast om de nieuw gemaakte authenticator op te nemen.

De Authenticator-weergave

De Authenticator-weergave

Elke keer dat een authenticator wordt geëmuleerd, voegen we een sectie toe aan de authenticatorweergave om deze weer te geven. Elke authenticatorsectie bevat een naam, ID, configuratieopties, knoppen om de authenticator te verwijderen of actief te maken, en een referentietabel.

De Authenticator-naam

De naam van de authenticator is aanpasbaar en is standaard 'Authenticator', samengevoegd met de laatste vijf tekens van de ID. Oorspronkelijk was de naam van de authenticator de volledige ID en onveranderlijk. We hebben aanpasbare namen geïmplementeerd, zodat de gebruiker de authenticator kan labelen op basis van zijn mogelijkheden, de fysieke authenticator die hij moet emuleren, of een bijnaam die iets gemakkelijker te verteren is dan een ID van 36 tekens.

Referenties tabel

We hebben aan elke authenticatorsectie een tabel toegevoegd met alle inloggegevens die door een authenticator zijn geregistreerd. Binnen elke rij bieden we informatie over een inloggegevens, evenals knoppen om de inloggegevens te verwijderen of te exporteren.

Momenteel verzamelen we de informatie om deze tabellen te vullen door de CDP te ondervragen om de geregistreerde inloggegevens voor elke authenticator te verkrijgen. In de toekomst zijn we van plan een evenement toe te voegen voor het maken van inloggegevens.

De knop Actief

We hebben ook een Actief keuzerondje toegevoegd aan elke authenticatiesectie. De authenticator die momenteel actief is, zal de enige zijn die naar inloggegevens luistert en deze registreert. Zonder dit is het registreren van inloggegevens met meerdere authenticators niet-deterministisch, wat een fatale fout zou zijn bij het testen van WebAuthn met behulp ervan.

We hebben de actieve status geïmplementeerd met behulp van de SetUserPresence -methode op virtuele authenticators. De SetUserPresence- methode bepaalt of tests van de aanwezigheid van gebruikers slagen voor een bepaalde authenticator. Als we het uitschakelen, kan een authenticator niet naar inloggegevens luisteren. Door ervoor te zorgen dat deze voor maximaal één authenticator (degene die als actief is ingesteld) is ingeschakeld en de gebruikersaanwezigheid voor alle andere uit te schakelen, kunnen we deterministisch gedrag afdwingen.

Een interessante uitdaging waarmee we te maken kregen bij het toevoegen van de actieve knop was het vermijden van een raceconditie. Overweeg het volgende scenario:

  1. De gebruiker klikt op het keuzerondje Actief voor Authenticator X en verzendt een verzoek naar de CDP om X als actief in te stellen. Het keuzerondje Actief voor X is geselecteerd en alle andere zijn uitgeschakeld.

  2. Onmiddellijk daarna klikt de gebruiker op het keuzerondje Actief voor Authenticator Y, waardoor een verzoek naar de CDP wordt verzonden om Y als actief in te stellen. Het keuzerondje Actief voor Y is geselecteerd en alle andere, inclusief voor X, zijn uitgeschakeld.

  3. In de backend wordt de oproep om Y als actief in te stellen voltooid en opgelost. Y is nu actief en alle andere authenticators niet.

  4. In de backend wordt de oproep om X als actief in te stellen voltooid en opgelost. X is nu actief en alle andere authenticators, inclusief Y, zijn dat niet.

De resulterende situatie is nu als volgt: X is de actieve authenticator. Het keuzerondje Actief voor X is echter niet geselecteerd. Y is niet de actieve authenticator. Het keuzerondje Actief voor Y is echter geselecteerd. Er is een meningsverschil tussen de voorkant en de feitelijke status van de authenticatoren. Dat is duidelijk een probleem.

Onze oplossing: Breng pseudo-tweerichtingscommunicatie tot stand tussen de keuzerondjes en de actieve authenticator. Ten eerste onderhouden we een variabele activeId in de weergave om de ID van de momenteel actieve authenticator bij te houden. Vervolgens wachten we tot de aanroep om een ​​actieve authenticator in te stellen terugkeert en stellen we activeId in op de ID van die authenticator. Ten slotte doorlopen we elke authenticatiesectie. Als de ID van die sectie gelijk is aan activeId , zetten we de knop op geselecteerd. Anders stellen we de knop in op gedeselecteerd.

Hier ziet u hoe dat eruit ziet:


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

Gebruiksstatistieken

We wilden het gebruik van deze functie volgen. In eerste instantie kwamen we met twee opties.

  1. Tel elke keer dat het tabblad WebAuthn in DevTools werd geopend . Deze optie kan mogelijk tot overtelling leiden, omdat iemand het tabblad kan openen zonder het daadwerkelijk te gebruiken.

  2. Houd bij hoe vaak het selectievakje 'Virtuele authenticatoromgeving inschakelen' in de werkbalk is aangevinkt . Deze optie had ook een potentieel probleem met overtelling, omdat sommige de omgeving meerdere keren in dezelfde sessie in- en uitschakelen.

Uiteindelijk hebben we besloten om voor het laatste te gaan, maar het tellen te beperken door te controleren of de omgeving al was ingeschakeld in de sessie . Daarom verhogen we het aantal alleen met 1, ongeacht hoe vaak de ontwikkelaar de omgeving heeft gewijzigd. Dit werkt omdat er elke keer dat het tabblad opnieuw wordt geopend een nieuwe sessie wordt gemaakt, waardoor de controle opnieuw wordt ingesteld en de statistiek opnieuw kan worden verhoogd.

Samenvatting

Bedankt voor het lezen! Als u suggesties heeft om het tabblad WebAuthn te verbeteren, kunt u ons dit laten weten door een bug in te dienen.

Hier vindt u enkele bronnen als u meer wilt weten over WebAuthn:

Download de voorbeeldkanalen

Overweeg om Chrome Canary , Dev of Beta te gebruiken als uw standaard ontwikkelingsbrowser. Met deze voorbeeldkanalen krijgt u toegang tot de nieuwste DevTools-functies, kunt u geavanceerde webplatform-API's testen en kunt u problemen op uw site opsporen voordat uw gebruikers dat doen!

Neem contact op met het Chrome DevTools-team

Gebruik de volgende opties om de nieuwe functies, updates of iets anders gerelateerd aan DevTools te bespreken.