WebAuthn-Passwortlos-Login
Doggy implementiert die WebAuthn-Standardauthentifizierung auf Basis von web-auth/webauthn-symfony-bundle und unterstützt Login mit Fingerabdruck, Gesichtserkennung und Sicherheitsschlüssel.
Übersicht
WebAuthn-Anmeldeinformationen werden in src/Entity/Security/WebauthnCredential.php (Tabelle webauthn_credentials) gespeichert und mit App\Entity\Organization\Employee (Benutzerentität) verknüpft.
Das Zertifikats-Repository implementiert PublicKeyCredentialSourceRepositoryInterface und unterstützt das Speichern und Abfragen von WebAuthn-Anmeldeinformationen.
Konfiguration
yaml
# config/packages/webauthn.yaml
webauthn:
credential_repository: 'App\Repository\Security\WebauthnCredentialRepository'
user_repository: 'App\Repository\Organization\EmployeeRepository'
creation_profiles:
default:
rp:
name: '%env(RELYING_PARTY_NAME)%'
id: '%env(RELYING_PARTY_ID)%'
public_key_credential_parameters:
- -7 # ES256
- -257 # RS256
authenticator_selection_criteria:
resident_key: required
user_verification: required
request_profiles:
default:
rp_id: '%env(RELYING_PARTY_ID)%'
user_verification: required
allowed_origins: ['http://localhost:8000']Firewall-Konfiguration
yaml
# config/packages/security.yaml
security:
firewalls:
main:
custom_authenticator: App\Security\AppCustomAuthenticator
webauthn:
success_handler: App\Security\WebauthnSuccessHandler
authentication:
enabled: true
routes:
options_path: '/login/webauthn/options'
result_path: '/login/webauthn/result'Verwaltung der Anmeldeinformationen
php
// src/Entity/Security/WebauthnCredential.php
class WebauthnCredential
{
private string $publicKeyCredentialId;
private string $type; // 'public-key'
private array $transports; // ['usb', 'nfc', 'internal']
private string $attestationType;
private string $credentialPublicKey;
private string $userHandle; // Employee ID
private int $counter;
private ?string $deviceName; // 如 "Chrome on Mac"
#[ORM\ManyToOne(targetEntity: Employee::class, inversedBy: 'passkeys')]
private ?Employee $employee = null;
}Login-Ablauf
Passkey registrieren
- Nach dem Login in die Sicherheitseinstellungen gehen (
/user/webauthn/register/options) - Der Browser ruft die WebAuthn-API zur Erstellung der Anmeldeinformationen auf
- Das Ergebnis wird an
/user/webauthn/register/resultgesendet - Die öffentlichen Schlüssel werden in der Tabelle
webauthn_credentialsgespeichert
Passwortlos-Login
- Benutzername eingeben, auf „Passkey-Login" klicken
- POST an
/login/webauthn/options, um die Challenge abzurufen - Der Browser signiert über die WebAuthn-API
- Das Ergebnis wird an
/login/webauthn/resultgesendet WebauthnSuccessHandlerverarbeitet den erfolgreichen Login (erfasst Gerät, aktualisiert Zeitstempel)
Erfolgs-Handler
App\Security\WebauthnSuccessHandler führt nach erfolgreichem Login Folgendes aus:
- Zeitstempel der letzten Nutzung der Anmeldeinformationen aktualisieren
- Gerätename automatisch erkennen (User-Agent-Analyse)
- Prüfen, ob es sich um den ersten Login handelt, und zur Passwortänderung führen
- Passwort-Reset-Ablauf unterstützen
WebAuthn-Anmeldeinformations-Repository
App\Repository\Security\WebauthnCredentialRepository implementiert:
findOneByCredentialId(): Anmeldeinformationen suchenfindAllForUserEntity(): alle Anmeldeinformationen eines Benutzers abrufensaveCredentialSource(): Anmeldeinformationen erstellen/aktualisierenparseUserAgent(): Gerätenamen-Erkennung