メインコンテンツまでスキップ

パスワードレス認証


前提知識

このドキュメントを理解するには、以下の基礎知識が役立ちます:


概要

idp-serverは、パスワードレス認証をサポートします。

パスワードレス認証とは、パスワードを使用せずにユーザーを認証する方式です。生体認証やセキュリティキーなど、より安全で使いやすい認証手段を提供します。

ユーザー ──[生体認証/セキュリティキー]──> 認証器 ──[署名]──> idp-server ──[検証]──> 認証成功

idp-serverでは以下のパスワードレス認証方式に対応しています:

  • FIDO2/WebAuthn: 生体認証、セキュリティキー
  • Passkey: デバイス間で同期可能な認証資格情報
  • FIDO UAF: モバイルアプリ向け生体認証(CIBA連携)

なぜパスワードレス認証が必要か

パスワードの課題

パスワード認証には多くの課題があります:

課題内容影響
フィッシング偽サイトでパスワードを盗まれるアカウント乗っ取り
使い回し同じパスワードを複数サイトで使用漏洩時の被害拡大
覚えられない複雑なパスワードは記憶困難ユーザー体験の低下
管理コストリセット対応、ポリシー管理運用負荷

パスワードレス認証のメリット

メリット説明
フィッシング耐性認証器がオリジン(ドメイン)を検証するため、偽サイトでは認証不可
利便性指紋や顔認証でワンタッチ認証
セキュリティ秘密鍵は認証器から出ない
運用コスト削減パスワードリセット対応が不要

idp-serverにおけるパスワードレス認証

1. FIDO2/WebAuthn

WebAuthn(Web Authentication API)は、W3Cが標準化したパスワードレス認証の仕様です。

ユーザー          ブラウザ          idp-server        認証器
| | | |
|--ログインボタン->| | |
| |--認証開始------->| |
| |<--challenge-----| |
| |--認証要求------------------------>|
|<--生体認証-------------------------------------|
|--指紋/顔---------------------------------------->|
| |<--署名---------------------------|
| |--署名検証------>| |
| |<--認証成功------| |

対応認証器:

  • プラットフォーム認証器: Touch ID, Face ID, Windows Hello
  • ローミング認証器: YubiKey, セキュリティキー

設定方法: FIDO2設定ガイド

2. Passkey

Passkeyは、FIDO2の拡張で、デバイス間で認証資格情報を同期できる機能です。

┌─────────────────────────────┐  ┌─────────────────────────────┐
│ Apple │ │ Google │
│ │ │ │
│ iPhone ──┐ │ │ Android ──┐ │
│ ├──> iCloud │ │ ├──> Google │
│ Mac ─────┘ Keychain │ │ Chrome ───┘ Password │
│ │ │ Manager │
└─────────────────────────────┘ └─────────────────────────────┘

メリット:

  • デバイス紛失時も他のデバイスで認証可能
  • 新しいデバイスへの移行が容易
  • ユーザー体験の向上

詳細: Passkeyの基礎


ユーザーとパスキーの関係

データモデル

idp-serverでは、ユーザーとパスキー(FIDO2クレデンシャル)は以下の関係で管理されます。1デバイス = 1クレデンシャルの設計を採用しています。

User (ユーザー)
└── AuthenticationDevice (認証デバイス) [1:N]
├── credential_type: クレデンシャルタイプ (fido2, jwt_bearer等)
├── credential_id: クレデンシャルID
├── credential_payload: クレデンシャル固有データ
│ └── FIDO2の場合:
│ - credential_id: WebAuthnクレデンシャルID
│ - rp_id: Relying Party ID
│ - fido_server_id: FIDOサーバーID
│ - public_key: 公開鍵
└── credential_metadata: メタデータ(登録日時等)

関係性

エンティティ説明関係
Userユーザーアカウント1ユーザーに複数の認証デバイスを登録可能
AuthenticationDevice認証に使用するデバイス(iPhone、Mac等)1デバイス = 1クレデンシャル(統合設計)

1デバイス = 1クレデンシャル設計

この設計には以下のメリットがあります:

メリット説明
シンプルなデータモデルデバイスとクレデンシャルの1:1対応で管理が容易
直感的なUIユーザーはデバイス単位でパスキーを管理
効率的なクエリJOINなしでデバイスとクレデンシャルを取得可能
明確なライフサイクルデバイス削除 = クレデンシャル削除

複数のパスキーを登録する場合は、それぞれ別のAuthenticationDeviceとして登録されます。

制約事項

制約内容
rpIdの一致登録時のrpIdと認証時のrpIdが一致する必要がある
rpIdのスコープrpIdは現在のドメインまたはその親ドメインのみ指定可能
クレデンシャルの一意性同一rpId内でcredential_idは一意
1:1対応1つのAuthenticationDeviceに1つのクレデンシャルのみ

FIDO2のusername

パスキー登録・認証時に使用されるusernameの仕様です。

WebAuthn仕様の詳細: FIDO2登録フローとインターフェースを参照してください。

アーキテクチャ

idp-serverは、FIDOサーバーの実装を抽象化しています。

┌─────────────────────────────────────────────────────────────┐
│ idp-server │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Fido2RegistrationInteractor │ │
│ │ Fido2AuthenticationInteractor │ │
│ │ └── username解決(TenantIdentityPolicy) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────┴────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────────┐ ┌─────────────────────────────┐ │
│ │ WebAuthn4j Adapter │ │ External FIDO Server │ │
│ │ (built-in) │ │ (http_request経由) │ │
│ └─────────────────────┘ └─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

usernameの決定ルール

TenantIdentityPolicyuniqueKeyType設定に基づいてusernameを決定します。

uniqueKeyTypeusernameの値用途
USERNAMEpreferredUsername社内システム(従業員ID)
EMAILemail一般向けWebサービス(デフォルト
PHONEphoneNumberモバイルアプリ(SMS認証)
EXTERNAL_USER_IDexternalUserId外部IdP連携

この解決はFido2RegistrationInteractorで行われ、FIDOサーバーの実装(WebAuthn4j / 外部サーバー)に依存しません。

usernameの流れ

┌──────────────────────────────────────────────────────────────┐
│ パスキー登録フロー │
├──────────────────────────────────────────────────────────────┤
│ 1. フロントエンド → idp-server │
│ └── username を送信(TenantIdentityPolicyに基づく値) │
│ │
│ 2. idp-server → FIDOサーバー │
│ └── username を含むリクエストを転送 │
│ └── WebAuthn4j または 外部FIDOサーバー │
│ │
│ 3. FIDOサーバー → 認証器 │
│ └── user.name として認証器UIに表示・保存 │
│ │
│ 4. FIDOサーバー → idp-server │
│ └── レスポンスにusernameを含める │
│ └── metadata.username_param で取得キーを指定 │
└──────────────────────────────────────────────────────────────┘

FIDO2設定

metadata.username_paramで、FIDOサーバーのレスポンスからusernameを取得するパラメータ名を指定します。

WebAuthn4j Adapter(built-in)の場合:

{
"type": "fido2",
"metadata": {
"username_param": "username"
},
"interactions": {
"fido2-registration": {
"execution": {
"function": "webauthn4j_registration"
}
}
}
}

外部FIDOサーバーの場合:

{
"type": "fido2",
"metadata": {
"username_param": "user_id"
},
"interactions": {
"fido2-registration": {
"execution": {
"function": "http_request",
"http_request": {
"url": "https://fido-server.example.com/registration"
}
}
}
}
}

外部FIDOサーバーを使用する場合、レスポンスのどのフィールドにusernameが含まれるかはサーバー実装に依存するため、username_paramで適切に指定してください。

注意事項

注意点説明
一意性usernameはテナント内で一意である必要がある
不変性登録後のusername変更は新規パスキー登録が必要
64バイト制限WebAuthn仕様により、認証器で切り詰められる可能性あり
FIDOサーバー依存外部サーバー使用時はusername_paramの設定が重要

rpIdとサブドメインの関係

WebAuthn仕様では、rpIdの有効性は以下のルールで判定されます。

ケース有効性
完全一致ホスト: auth.local.test / rpId: auth.local.test有効
親ドメインホスト: auth.local.test / rpId: local.test有効
兄弟ドメインホスト: auth.local.test / rpId: api.local.test無効
無関係なドメインホスト: auth.local.test / rpId: example.com無効

推奨: サブドメイン構成では、親ドメイン(例: local.test)をrpIdとして設定することで、複数のサブドメイン間でパスキーを共有できます。

1ユーザー複数パスキー

ユーザーは複数のパスキーを登録できます。各パスキーは個別のAuthenticationDeviceとして管理されます:

  • バックアップ用: デバイス紛失時のリカバリー
  • 複数デバイス: iPhone、Mac、セキュリティキーなど
  • 異なるrpId: サブドメインごとに異なるパスキー(非推奨)
User: alice@example.com
├── AuthenticationDevice: "iPhone 15"
│ ├── credential_type: "fido2"
│ └── credential_payload: { rp_id: "example.com", ... }
├── AuthenticationDevice: "MacBook Pro"
│ ├── credential_type: "fido2"
│ └── credential_payload: { rp_id: "example.com", ... }
└── AuthenticationDevice: "YubiKey 5"
├── credential_type: "fido2"
└── credential_payload: { rp_id: "example.com", ... }

デバイス情報の自動抽出

パスキー登録時、idp-serverはHTTPリクエストのUser-Agentヘッダーを解析し、AuthenticationDeviceのフィールドを自動設定します。これにより、ユーザーは登録済みパスキーを識別しやすくなります。

User-Agent解析の仕組み

User-Agent ヘッダー


┌─────────────────────────────────────┐
│ DeviceInfo.parse() │
│ ┌──────────────────────────────┐ │
│ │ 1. デバイス種別判定 │ │
│ │ 2. OS判定 + バージョン抽出 │ │
│ │ 3. ブラウザ判定 + バージョン │ │
│ │ 4. モバイル判定 │ │
│ └──────────────────────────────┘ │
└─────────────────────────────────────┘


AuthenticationDevice フィールド設定

フィールドマッピング

AuthenticationDeviceDeviceInfo説明
app_nametoLabel()デバイスラベル"iPhone - Safari (iOS 17.2)"
platformplatform()プラットフォーム"Mobile" / "Desktop"
osos()OS名"iOS", "macOS", "Windows"
modelmodel()ブラウザ+バージョン"Safari 17.2", "Chrome 120"

User-Agent解析ルール

デバイス種別判定:

User-Agent含有文字列デバイス
iphoneiPhone
ipadiPad
android + mobileAndroid Phone
androidAndroid Tablet
macintosh, mac osMac
windowsWindows PC
linuxLinux

OS判定:

User-Agent含有文字列OS
iphone, ipad, ipodiOS
androidAndroid
macintosh, mac osmacOS
windowsWindows
linuxLinux

OSバージョン抽出(正規表現):

OSパターン抽出結果
iOS(?:iPhone|CPU) OS (\d+[_.]\d+(?:[_.]\d+)?)iPhone OS 17_2_117.2.1
macOSMac OS X (\d+[_.]\d+(?:[_.]\d+)?)Mac OS X 10_15_710.15.7
AndroidAndroid (\d+(?:\.\d+)?)Android 1414
WindowsWindows NT (\d+\.\d+)Windows NT 10.010/11

ブラウザ判定(判定順序が重要):

判定条件ブラウザ
edg/ または edge/Edge
firefoxFirefox
chrome かつ edgを含まないChrome
safari かつ chrome, chromiumを含まないSafari
opera または opr/Opera

ブラウザバージョン抽出:

ブラウザパターン抽出結果
EdgeEdg/(\d+)Edg/120.0.0.0120
FirefoxFirefox/(\d+(?:\.\d+)?)Firefox/121.0121
ChromeChrome/(\d+)Chrome/120.0.0.0120
SafariVersion/(\d+(?:\.\d+)?)Version/17.217.2
OperaOPR/(\d+)OPR/106.0106

解析結果例

Safari on iPhone:

User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 17_2_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Mobile/15E148 Safari/604.1

→ app_name: "iPhone - Safari (iOS 17.2.1)"
→ platform: "Mobile"
→ os: "iOS"
→ model: "Safari 17.2"

Chrome on Mac:

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36

→ app_name: "Mac - Chrome (macOS 10.15.7)"
→ platform: "Desktop"
→ os: "macOS"
→ model: "Chrome 120"

Edge on Windows:

User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0

→ app_name: "Windows PC - Edge (Windows 10/11)"
→ platform: "Desktop"
→ os: "Windows"
→ model: "Edge 120"

実装クラス

  • DeviceInfo.java - User-Agent解析とフィールド抽出
  • UserAgent.java - User-Agentラッパー、toDeviceInfo()メソッド
  • Fido2RegistrationInteractor.java - 登録時のデバイス情報設定

パスキーの削除(登録解除)

ユーザーは登録済みのパスキーを削除できます。idp-serverはステップアップ認証をサポートしており、パスキー削除時に追加の認証を要求できます。

削除フロー

ユーザー          フロントエンド          idp-server
| | |
|--削除ボタン------->| |
| |--DELETE /me/authentication-devices/{id}-->|
| | |--ステップアップ認証が必要か判定
| |<--401 step_up_authentication_required-----|
|<--再認証要求-------| |
|--パスキー認証----->| |
| |--DELETE (認証済み)->|
| | |--デバイス削除
| |<--204 No Content---|
|<--削除完了---------| |

ステップアップ認証

パスキー削除などのセキュリティ上重要な操作には、ステップアップ認証を要求できます。

レスポンス例(認証が必要な場合):

{
"status": "step_up_authentication_required",
"message": "Additional authentication is required for this operation"
}

レスポンス例(成功):

{
"status": "OK"
}

実装クラス

  • Fido2DeregistrationInteractor.java - パスキー削除のインターアクター
  • WebAuthn4jDeregistrationExecutor.java - WebAuthn4jでの削除実行
  • UserOperationEntryService.java - ステップアップ認証判定

注意事項

注意点説明
最後のパスキー最後のパスキーを削除すると、パスワードレス認証ができなくなる
ステップアップ認証セキュリティ設定により、削除時に追加認証が必要な場合がある
FIDOサーバー連携外部FIDOサーバー使用時は、サーバー側でも削除が必要な場合がある

3. FIDO UAF(CIBA連携)

FIDO UAF(Universal Authentication Framework)は、モバイルアプリ向けの生体認証仕様です。idp-serverでは、CIBA(Client Initiated Backchannel Authentication)と組み合わせて使用できます。

クライアント      idp-server      モバイルアプリ      ユーザー
| | | |
|--CIBA認証----->| | |
| リクエスト |--プッシュ通知-->| |
| | |--生体認証要求->|
| | |<--指紋/顔------|
| |<--認証完了------| |
|<--トークン発行-| | |

ユースケース:

  • コールセンターでの本人確認
  • 決済承認
  • 高セキュリティ操作の承認

詳細: CIBAフロー


認証ポリシーとの連携

パスワードレス認証は、認証ポリシーと組み合わせて使用します。

段階的な導入

推奨される導入ステップ:

  1. Phase 1: パスワード + FIDO2(オプション)
  2. Phase 2: FIDO2推奨、パスワードはフォールバック
  3. Phase 3: FIDO2のみ(パスワードレス完全移行)

MFAとの組み合わせ

FIDO2は単独でMFAの要件を満たすことができます:

認証要素FIDO2での実現
所持認証器(スマートフォン、セキュリティキー)
生体指紋、顔認証
知識PIN(オプション)

セキュリティ考慮事項

フィッシング耐性

FIDO2/WebAuthnは設計上フィッシング耐性があります:

  • オリジン検証: 認証器が登録時のドメインと照合
  • 署名バインディング: challengeとオリジンを含めて署名

認証器の紛失対応

  • 複数認証器の登録: バックアップ用の認証器を推奨
  • リカバリーフロー: 管理者による認証器リセット機能

デバイス管理のセキュリティ

パスキーの登録・削除は、セキュリティ上重要な操作です。idp-serverは以下のセキュリティ機能を提供します:

機能説明
ステップアップ認証デバイス削除時に追加認証を要求可能
セキュリティイベントデバイス登録・削除をイベントとして記録
監査ログ操作履歴の追跡が可能

認証器の検証(Attestation)

**Attestation(アテステーション)**とは、パスキー登録時に認証器(Authenticator)の真正性を検証する仕組みです。認証器が生成した署名とともに、認証器自体の情報(メーカー、モデル、セキュリティ特性など)を証明するデータを提供します。

Attestationの構成要素

認証器 ──[公開鍵 + Attestation Statement]──> サーバー

├── format: アテステーション形式
├── attStmt: 署名データ
└── authData: 認証器データ(AAGUID含む)
要素説明
AAGUID認証器モデルを識別する128bit UUID
Attestation Statement認証器の署名(形式はformatで指定)
Attestation Format署名形式(none, packed, tpm, android-key等)

Attestation形式(Format)

登録時のレスポンスに含まれる署名形式です。

形式説明対応認証器
noneアテステーションなしプラットフォーム認証器(プライバシー保護)
packedFIDO2標準形式セキュリティキー(YubiKey等)
tpmTPMによる署名Windows Hello(TPM搭載PC)
android-keyAndroid KeystoreAndroid端末
android-safetynetSafetyNet API旧Android認証
appleApple Anonymous AttestationApple端末(iOS/macOS)
fido-u2f旧U2F形式旧型セキュリティキー

Attestation Conveyance(クライアントへの要求)

サーバーからクライアントへの登録オプションで、アテステーションの要求レベルを指定します。

説明ユースケース
noneアテステーション不要一般向けサービス(プライバシー優先)
indirect匿名化されたアテステーション中間的なセキュリティ要件
direct完全なアテステーションエンタープライズ(認証器種別の制限)
enterprise企業向けアテステーション管理デバイスの識別

注意: directenterpriseを要求しても、プラットフォーム認証器(Touch ID、Face ID等)はプライバシー保護のためnone形式で応答することがあります。これはWebAuthn仕様で許容されており、正常な動作です。

idp-serverでのAttestation検証パターン

idp-serverは3つのアテステーション検証パターンをサポートします。

パターン説明設定
None(検証なし)アテステーションを検証しないデフォルト、一般向けサービス
TrustStore事前登録された証明書で検証特定認証器のみ許可
FIDO MDSFIDO Metadata Serviceで検証エンタープライズ、高セキュリティ

1. None(検証なし)

アテステーションの検証を行わず、どの認証器でも登録を許可します。

{
"webauthn4j": {
"attestation_preference": "none"
}
}
  • メリット: すべての認証器を許可、ユーザー体験を優先
  • デメリット: 認証器の信頼性を検証できない
  • 推奨: 一般消費者向けサービス

2. TrustStore(証明書ベース)

事前に登録した証明書で認証器を検証します。

{
"webauthn4j": {
"attestation_preference": "direct",
"trust_store": {
"certificates": [
"-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
]
}
}
}
  • メリット: 特定の認証器のみ許可可能
  • デメリット: 証明書の管理が必要
  • 推奨: 社内システム、特定セキュリティキーの強制

3. FIDO Metadata Service(MDS)

FIDO Allianceが提供するメタデータサービスを使用して認証器を検証します。

{
"webauthn4j": {
"attestation_preference": "direct",
"mds": {
"enabled": true,
"cache_ttl_seconds": 86400
}
}
}
  • メリット: 最新の認証器情報、脆弱性情報を自動取得
  • デメリット: ネットワーク接続が必要、MDSに登録されていない認証器は検証不可
  • 推奨: エンタープライズ、金融サービス

FIDO Metadata Service(MDS)

FIDO MDSは、FIDO Allianceが運営する認証器のメタデータ配信サービスです。

MDSで取得できる情報:

情報説明
認証器名YubiKey 5 NFC、iPhone等
アイコン認証器のアイコン画像(Base64)
認証レベルFIDO認定レベル(L1, L2, L3)
ステータス正常、脆弱性あり、失効等
対応アルゴリズムES256、RS256等

認証器ステータス:

ステータス説明対応
FIDO_CERTIFIEDFIDO認定済み許可
FIDO_CERTIFIED_L1/L2/L3認定レベル別許可
UPDATE_AVAILABLEファームウェア更新あり警告
ATTESTATION_KEY_COMPROMISE鍵が漏洩拒否
USER_VERIFICATION_BYPASSUVバイパス脆弱性拒否
REVOKED失効拒否

idp-serverは登録時にMDSをチェックし、危殆化した認証器を検出した場合は警告をログに出力します。

MDSキャッシュ:

MDSデータはCacheStoreにキャッシュされ、不要なネットワーク通信を防ぎます。

キャッシュキー内容TTL
mds:entries全認証器メタデータ24時間(設定可能)
mds:status:{aaguid}認証器ステータス24時間(設定可能)
mds:last_fetch最終取得時刻24時間(設定可能)

プラットフォーム認証器の制限

Apple(Touch ID、Face ID)やAndroid等のプラットフォーム認証器は、プライバシー保護のためアテステーションを提供しないことがあります。

プラットフォームアテステーション備考
Apple(iOS/macOS)noneまたはapple(匿名)MDSに未登録
Androidandroid-key一部端末のみ
Windows Hellotpm(TPM搭載時)TPM非搭載PCはnone

重要: attestation: "direct"を要求しても、プラットフォーム認証器がnoneで応答することは仕様上正常です。idp-serverはこのケースを適切に処理します。

推奨設定

ユースケース推奨設定
一般消費者向けサービスattestation_preference: "none"、MDS無効
企業内システムattestation_preference: "direct"、TrustStoreで許可認証器を限定
金融・医療など高セキュリティattestation_preference: "direct"、MDS有効、危殆化チェック
政府・防衛attestation_preference: "enterprise"、MDS有効、FIDO認定必須

関連ドキュメント


関連ドキュメント

基礎知識

設定

プロトコル


参考仕様