Skip to content

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

  1. Nach dem Login in die Sicherheitseinstellungen gehen (/user/webauthn/register/options)
  2. Der Browser ruft die WebAuthn-API zur Erstellung der Anmeldeinformationen auf
  3. Das Ergebnis wird an /user/webauthn/register/result gesendet
  4. Die öffentlichen Schlüssel werden in der Tabelle webauthn_credentials gespeichert

Passwortlos-Login

  1. Benutzername eingeben, auf „Passkey-Login" klicken
  2. POST an /login/webauthn/options, um die Challenge abzurufen
  3. Der Browser signiert über die WebAuthn-API
  4. Das Ergebnis wird an /login/webauthn/result gesendet
  5. WebauthnSuccessHandler verarbeitet den erfolgreichen Login (erfasst Gerät, aktualisiert Zeitstempel)

Erfolgs-Handler

App\Security\WebauthnSuccessHandler führt nach erfolgreichem Login Folgendes aus:

  1. Zeitstempel der letzten Nutzung der Anmeldeinformationen aktualisieren
  2. Gerätename automatisch erkennen (User-Agent-Analyse)
  3. Prüfen, ob es sich um den ersten Login handelt, und zur Passwortänderung führen
  4. Passwort-Reset-Ablauf unterstützen

WebAuthn-Anmeldeinformations-Repository

App\Repository\Security\WebauthnCredentialRepository implementiert:

  • findOneByCredentialId(): Anmeldeinformationen suchen
  • findAllForUserEntity(): alle Anmeldeinformationen eines Benutzers abrufen
  • saveCredentialSource(): Anmeldeinformationen erstellen/aktualisieren
  • parseUserAgent(): Gerätenamen-Erkennung

Open Source unter MIT | Copyright © 2026 Doggy