EN · DE · RU · FR · ES

#2762: webauthn.js

projectforge-webapp/src/utilities/webauthn.js Dienstprogramme zur Konvertierung von WebAuthn-Anmeldeinformationen · projectforge-webapp/src/utilities/webauthn-json.js 86 Zeilen · 80 Code · 1 Kommentar · 5 leer
ProjectForge's handgefertigte WebAuthn (FIDO2/U2F) Konvertierungsschicht für Anmeldeinformationen. Dieses Modul stellt die Kodierungs-/Dekodierungsbrücke zwischen der nativen PublicKeyCredential-API des Browsers (die binäre ArrayBuffer-Werte verwendet) und der serverseitigen JSON-API (die base64url-kodierte Zeichenfolgen erwartet) bereit. Drei Hauptfunktionen kümmern sich um unterschiedliche Lebenszyklusphasen: convertPublicKeyCredentialRequestOptions dekodiert vom Server bereitgestellte Challenge-/Benutzer-IDs in ArrayBuffer-Form für die Browser-API; convertRegisterCredential verpackt eine neu erstellte Anmeldeinformation in die JSON-Form, die der Server für die Registrierung erwartet; convertAuthenticateCredential macht dasselbe für Authentifizierungsassertionen.

Architektur

Interne Helfer

decodeBase64url — Konvertiert eine URL-sichere base64-Zeichenfolge in einen ArrayBuffer. Verwendet die atob-Brücke: Rekonstruiert zunächst Standard-Base64 (Ersetzung von -+, _/, Hinzufügen von Padding), dekodiert dann über atob und kopiert den charCode jedes Zeichens in ein Uint8Array, das von einem neuen ArrayBuffer gestützt wird.

bufferToBase64url — Die Umkehrung: Iteriert über eine Uint8Array-Ansicht, erstellt einen binären String via String.fromCharCode, kodiert mit btoa und konvertiert dann in die URL-sichere Form.

convertCredentials — Helfer, der während der Refaktorisierung extrahiert wurde und ein Array von Credential-Descriptor-Objekten (mit rawId- und id-Feldern) von base64url-Strings in ArrayBuffer konvertiert, sowohl für allowCredentials- als auch für excludeCredentials-Listen.

Registrierung vs. Authentifizierung

Registrierung (convertRegisterCredential) verpackt: rawId, clientDataJSON, attestationObject und transports aus der Credential-Antwort, plus Anfragemetadaten (requestId, challenge, sessionToken). Authentifizierung (convertAuthenticateCredential) verpackt: authenticatorData, signature, userHandle anstelle der Attestierungsfelder. Beide verpacken das Ergebnis in dieselbe Hüllenstruktur, die die serverseitigen REST-Endpunkte erwarten.

Entwicklung des Ansatzes

Diese Datei repräsentiert die produktive WebAuthn-Implementierung, die sich von der eingekauften webauthn-json.js-Bibliothek unterscheidet. Das Team begann mit manueller Bit-Manipulation-Base64-Dekodierung (unter Verwendung einer Reverse-Lookup-Tabelle) und refaktorierte dann zu dem einfacheren atob/btoa-basierten Ansatz. Die separaten Registrierungs-/Authentifizierungsfunktionen und der convertCredentials-Helfer wurden aus einer anfänglich monolithischen Credential-Konvertierung extrahiert.

Git-Verlauf

CommitWas sich geändert hat
9c86a74e5Extraktion der Inline-allowCredentials/excludeCredentials-Konvertierungsschleifen in eine gemeinsame Helferfunktion convertCredentials(dest, src). Reduzierte Doppelarbeit: Beide Credential-Listen rufen nun denselben Helfer auf. Die excludeCredentials-Konvertierung aus dem ursprünglichen convertPublicKeyCredentialRequestOptions wurde hier ebenfalls hinzugefügt, wodurch die Credential-Listenverarbeitung vervollständigt wurde.
c6ba8d11cZwei bedeutende Ergänzungen: (1) Hinzufügung der Credential-Listenkonvertierung innerhalb von convertPublicKeyCredentialRequestOptions zur Verarbeitung von allowCredentials-Arrays – rawId und id jedes Credentials werden aus base64url dekodiert; (2) Hinzufügung von convertAuthenticateCredential als dedizierte Funktion für Authentifizierungsassertionen (zuvor wurden Registrierung und Authentifizierung von einer einzigen convertCredential-Funktion behandelt). Die alte Funktion wurde zur Klarstellung in convertRegisterCredential umbenannt.
4c5cc21e9Refaktorisierung von convertCredential, um das Ergebnisobjekt direkt zurückzugeben, anstatt es einer Zwischenvariablen result zuzuweisen, und Hinzufügung des Feldes challenge zur Ausgabehülle – eine kritische Korrektur, da der Server die ursprüngliche Challenge benötigt, um das Credential zu verifizieren.
4a70ca329Behebung der Extraktion der Credential-Antwortfelder mittels Destrukturierung: const { response } = credential; – der vorherige Code las clientDataJSON, attestationObject und transports fälschlicherweise aus dem Objekt der obersten Ebene credential anstatt aus credential.response, was undefined-Werte erzeugt hätte. Dies war eine kritische Fehlerbehebung.
ddccb2e68Große Refaktorisierung des base64url-Kodierungs-/Dekodierungsansatzes. Der ursprüngliche handgefertigte Bit-Manipulations-Dekodierer (unter Verwendung einer Reverse-Lookup-Tabelle und manueller Bitverschiebung) wurde durch den einfacheren atob/btoa-basierten Ansatz ersetzt. Außerdem wurde convertPublicKeyCredentialRequestOptions von mutationsbasiert (Änderung der Eingabe an Ort und Stelle) zu kopierbasiert (Verwendung von JSON.parse(JSON.stringify(...)) zur Tiefenkopie zuerst) konvertiert. Erste Version von convertCredential für die Registrierungskodierung hinzugefügt.
05c32c27fErster WebAuthn-Commit: Erstellung des base64url-Dekodierers und der ersten Version von convertPublicKeyCredentialRequestOptions. Verwendung des Parameternamens registerData und Zugriff auf challenge/user.id über registerData.publicKey.challenge, was eine frühere API-Form widerspiegelt, die später vereinfacht wurde.