WebAuthn パスワードレスログイン
Doggy は web-auth/webauthn-symfony-bundle に基づいて WebAuthn 標準認証を実装し、指紋、顔認証、セキュリティキーによるログインをサポートします。
概要
WebAuthn 認証情報は src/Entity/Security/WebauthnCredential.php(テーブル webauthn_credentials)に保存され、App\Entity\Organization\Employee(ユーザーエンティティ)に関連付けられます。
認証情報リポジトリは PublicKeyCredentialSourceRepositoryInterface を実装し、WebAuthn 認証情報の保存とクエリをサポートします。
設定
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']セキュリティファイアウォール設定
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'認証情報管理
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;
}ログインフロー
Passkey の登録
- ユーザーはログイン後にセキュリティ設定へ入る(
/user/webauthn/register/options) - ブラウザが WebAuthn API を呼び出して認証情報を作成
- 結果を
/user/webauthn/register/resultに送信 - 公開鍵認証情報を
webauthn_credentialsテーブルに保存
パスワードレスログイン
- ユーザー名を入力し、「Passkey ログイン」をクリック
- POST を
/login/webauthn/optionsに送信してチャレンジを取得 - ブラウザが WebAuthn API を呼び出して署名
- 結果を
/login/webauthn/resultに送信 WebauthnSuccessHandlerがログイン成功を処理(デバイス記録、最終使用時間の更新)
サクセスハンドラー
App\Security\WebauthnSuccessHandler はログイン成功後に:
- 認証情報の最終使用時間を更新
- デバイス名を自動認識(User-Agent 解析)
- 初回ログインかをチェックし、パスワード変更をガイド
- パスワードリセットフローをサポート
WebAuthn 認証情報リポジトリ
App\Repository\Security\WebauthnCredentialRepository の実装:
findOneByCredentialId(): 認証情報を検索findAllForUserEntity(): ユーザーの全認証情報を取得saveCredentialSource(): 認証情報の作成/更新parseUserAgent(): デバイス名の識別