WebAuthn (Web Authentication API) is een W3C-standaard die veilige wachtwoordloze authenticatie mogelijk maakt met behulp van cryptografie met publieke sleutels. In plaats van wachtwoorden registreren en authenticeren gebruikers zich met behulp van op hardware gebaseerde authenticators (zoals vingerafdraaklezers, Face ID, YubiKeys, enz.) of platformauthenticators (ingebouwd, zoals Touch ID).
Hieronder vindt u hoe u de registratie en authenticatie kunt afhandelen met een Javascript-client.
Hoe WebAuthn-registratie werkt
Gebruiker start registratie:
The user provides a username and clicks Register.
Browser vraagt opties op bij server:
De frontend doet een POST-verzoek om registratieopties te verkrijgen.
Browser maakt referenties aan:
Via de navigator.credentials.create() API via SimpleWebAuthnBrowser.startRegistration() wordt een credential aangemaakt.
Server Verifies Registration:
De browser stuurt de credential terug naar de server.
De server verifieert de registratie en slaat de openbare sleutel op voor die gebruiker.
Het component TsgcWSAPIServer_WebAuthn bevat een HTML-bestand om het WebAuthn-protocol te testen. Dit HTML-bestand bevat een minimale gebruikersinterface en JavaScript om met WebAuthn te communiceren.
Walkthrough of sgcWebAuthn.html
Structuuroverzicht:
Username Input: Captures the user's identifier.
Buttons:
Register — initiates WebAuthn registration.
Authenticate — initiates login (handled similarly).
Debugconsole: Toont realtime-debuginformatie (JSON van WebAuthn).
1. HTML-gebruikersinterface voor invoer
<input type="text" id="username" name="username" autocomplete="username webauthn" />
<button id="btnRegBegin"><strong>Register</strong></button>
2. JavaScript: Button Click Handler
document.querySelector('#btnRegBegin').addEventListener('click', async () => {
const username = document.getElementById("username").value;
if (username == "") {
document.getElementById('Error').innerText = 'Please enter a username to register';
return;
}
const resp = await fetch('<#webauthn_registration_options>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, algorithms: [] })
});
const options = await resp.json();
const attResp = await startRegistration(options); // WebAuthn API
3. Server Response (Fake Endpoint in HTML)
fetch('/sgcWebAuthn/Registration/Options', ...)
fetch('/sgcWebAuthn/Registration/Verify', ...)
4. Registratie afronden
const verificationResp = await fetch('/webauthn/register/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(attResp)
});
const verificationJSON = await verificationResp.json();
if (verificationJSON && verificationJSON.verified) {
document.getElementById('Success').innerHTML = `Authenticator registered!`;
}
How WebAuthn Authentication works
Gebruiker start authenticatie:
The user provides a username and clicks Register.
Browser vraagt opties op bij server:
De frontend doet een POST-verzoek om authenticatieopties te verkrijgen.
Browser maakt referenties aan:
Gebruik van de navigator.credentials.get() API via SimpleWebAuthnBrowser.startAuthentication().
Server verifieert authenticatie:
De browser stuurt de referentie terug naar de server.
De server verifieert het ondertekende resultaat.
1. HTML UI Setup
<div class="container">
<h1>WebAuthn Authentication Sample</h1>
<section id="userdata">
<label for="username">Username:</label>
<input type="tekst" id="username" name="username" autocomplete="username webauthn" autofocus />
</section>
<button id="btnAuthBegin"><strong>Authenticate</strong></button>
<p id="Success" class="success"></p>
<p id="Error" class="error"></p>
<details open>
<summary>Console</summary>
<textarea id="Debug"></textarea>
</details>
</div>
2. Authenticatieopties ophalen
Voordat u startAuthentication aanroept, stuurt u de gebruikersnaam naar de server.
const resp = await fetch('<#webauthn_authentication_options>', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: document.getElementById("username").value,
user_verification: 'preferred'
}),
});
De server reageert met een JSON-object dat het volgende bevat:
{
"challenge": "base64url-encoded-random-string",
"allowCredentials": [
{
"id": "base64url-credential-id",
"type": "public-key"
}
],
"userVerification": "preferred",
"rpId": "yourdomain.com"
}
Dit wordt de PublicKeyCredentialRequestOptions genoemd.
3. Het authenticatorantwoord ontvangen
Het asseResp ziet er als volgt uit (vereenvoudigd):
{
"id": "credentialId",
"rawId": "base64url-encoded-id",
"response": {
"authenticatorData": "...",
"clientDataJSON": "...",
"signature": "...",
"userHandle": "..."
},
"type": "public-key",
"clientExtensionResults": {}
}
Dit antwoord bewijst dat de gebruiker:
4. Stuur het ondertekende authenticatieantwoord naar de server
Nadat de gebruiker interactie heeft gehad met zijn authenticator (via startAuthentication()), ontvangt u een responsobject in JavaScript.
const verificationResp = await fetch('/webauthn/authenticate/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(asseResp), // this is the signed response
});
5. Haal het antwoord van de server op
De server antwoordt met een resultaat als dit:
{ "verified": true }
Of als er iets fout is gegaan:
{ "verified": false, "error": "Invalid signature" }
En u verwerkt het in uw frontend-code:
const result = await verificationResp.json();
if (result.verified) {
document.getElementById('Success').textContent = 'User authenticated!';
} else {
document.getElementById('Error').textContent = 'Authentication failed!';
}