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

CIBAバインディングメッセージのバックエンド検証

このドキュメントの目的

CIBAフローにおけるバインディングメッセージのバックエンド検証を理解し、実装することが目標です。

学べること

  • バインディングメッセージ検証の基礎

    • バインディングメッセージの役割(フィッシング対策、トランザクション確認)
    • 消費デバイスと認証デバイス間の連動確認
    • OIDC CIBA仕様との関連
  • 実践的な知識

    • 認証デバイスでのバインディングメッセージ検証API
    • 認証ポリシーでの設定方法
    • エラーハンドリング

所要時間

約15分

前提条件

  • CIBA + FIDO-UAFの理解
  • テナントでCIBAが有効化されている
  • 認証デバイスが登録されている

バインディングメッセージとは

OIDC CIBA仕様での定義

OpenID Connect CIBA Core 1.0 - Section 7.1より:

The binding_message is intended to be displayed on both the consumption device and the authentication device to interlock them together for the transaction by way of a visual cue for the end-user.

binding_messageは、消費デバイスと認証デバイスを視覚的に連動させ、ユーザーがトランザクションを確認できるようにするためのメッセージです。

用途

用途説明
フィッシング対策ユーザーが正しいトランザクションを承認しているか確認確認コード: 1234
トランザクション確認金融取引等での取引内容確認振込: ¥50,000
セッション連動複数デバイス間でのセッション一致確認TX-ABCD-1234

フロー概要


API仕様

バインディングメッセージ検証エンドポイント

認証デバイスからバインディングメッセージの一致を検証するAPIです。

POST {tenant-id}/v1/authentications/{transaction-id}/authentication-device-binding-message
Content-Type: application/json

{
"binding_message": "999"
}

パスパラメータ

パラメータ説明
tenant-idstringテナント識別子
transaction-idstring認証トランザクションID(UUID)

リクエストボディ

フィールド必須説明
binding_messagestringユーザーが入力したバインディングメッセージ

レスポンス

成功時 (200 OK)

{}

失敗時 (400 Bad Request)

{
"error": "invalid_request",
"error_description": "Binding Message is unmatched"
}

エラーコード

エラー説明
invalid_request - "Binding Message is null"CIBAリクエストにbinding_messageが含まれていない
invalid_request - "Binding Message is unmatched"入力されたbinding_messageが一致しない

認証トランザクションの取得

認証デバイスは、まず認証トランザクション情報を取得してbinding_messageを表示します。

GET {tenant-id}/v1/authentication-devices/{device-id}/authentications?client_id=...

レスポンス例

{
"list": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"flow": "ciba",
"context": {
"binding_message": "999",
"scopes": "openid profile"
},
"client_attributes": {
"client_name": "My App"
}
}
]
}

context.binding_messageをユーザーに表示し、ユーザーが消費デバイスに表示されているメッセージと一致することを確認した上で入力させます。


実装例

認証デバイスアプリ(モバイル)での実装フロー

// 1. 認証トランザクション取得
const transactionResponse = await fetch(
`${baseUrl}/${tenantId}/v1/authentication-devices/${deviceId}/authentications?client_id=${clientId}`
);
const transactions = await transactionResponse.json();
const transaction = transactions.list[0];

// 2. ユーザーにbinding_messageを表示
// UI: "消費デバイスに表示されているコードを入力してください"
// UI: 期待値表示: transaction.context.binding_message (e.g., "999")

// 3. ユーザー入力を取得
const userInput = await getUserInput(); // ユーザーが入力した値

// 4. バインディングメッセージ検証API呼び出し
const verifyResponse = await fetch(
`${baseUrl}/${tenantId}/v1/authentications/${transaction.id}/authentication-device-binding-message`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ binding_message: userInput })
}
);

if (verifyResponse.status === 200) {
// 5. 検証成功 → 次の認証ステップへ(生体認証等)
await proceedToNextAuthentication(transaction);
} else {
// 6. 検証失敗 → エラー表示
const error = await verifyResponse.json();
showError(error.error_description);
}

認証ポリシーでの設定

バインディングメッセージ検証を認証フローに組み込むには、認証ポリシーで設定します。

設定例

{
"id": "ciba-binding-message-policy",
"name": "CIBA with Binding Message Verification",
"auth_flow": "ciba",
"conditions": {
"scopes": ["openid"]
},
"interactions": [
{
"type": "authentication-device-binding-message",
"required": true,
"order": 1
},
{
"type": "fido-uaf-authentication",
"required": true,
"order": 2
}
]
}

インタラクションタイプ

タイプ説明
authentication-device-binding-messageバインディングメッセージ検証
fido-uaf-authenticationFIDO-UAF認証
password-authenticationパスワード認証

セキュリティイベント

バインディングメッセージ検証の結果はセキュリティイベントとして記録されます。

イベントタイプ説明
authentication_device_binding_message_successバインディングメッセージ検証成功
authentication_device_binding_message_failureバインディングメッセージ検証失敗

Security Event Hookでの活用

検証失敗時にアラートを送信する設定例:

{
"type": "webhook",
"events": ["authentication_device_binding_message_failure"],
"endpoint": "https://your-webhook.example.com/alerts",
"method": "POST"
}

binding_messageの制約

長さ制限

idp-serverでは、binding_messageは最大20文字に制限されています。

// CibaRequestBaseVerifier.java
private static final int BINDING_MESSAGE_MAX_LENGTH = 20;

CIBA仕様より:

The binding_message SHOULD be relatively short and use a limited set of plain text characters.

推奨フォーマット

パターン用途
数字コード1234シンプルな確認
英数字コードTX-ABCDトランザクション識別
金額表示¥50,000金融取引確認

よくあるエラーと対処

エラー1: "Binding Message is null"

原因: CIBAリクエスト時にbinding_messageパラメータが指定されていない

対処: CIBAリクエストにbinding_messageを含める

curl -X POST "${TENANT_ID}/v1/backchannel/authentications" \
-d "login_hint=..." \
-d "binding_message=1234" \ # ← 追加
-d "scope=openid"

エラー2: "Binding Message is unmatched"

原因: ユーザーが入力したbinding_messageが元のリクエストと一致しない

対処:

  • ユーザーに正しいコードの再入力を促す
  • 消費デバイスに表示されているコードを確認するよう案内

関連ドキュメント


実装リファレンス

ファイル説明
AuthenticationDeviceBindingMessageInteractor.javaバインディングメッセージ検証実装
StandardAuthenticationInteraction.java認証インタラクションタイプ定義
DefaultSecurityEventType.javaセキュリティイベントタイプ

情報源:

  • libs/idp-server-authentication-interactors/src/main/java/org/idp/server/authentication/interactors/device/AuthenticationDeviceBindingMessageInteractor.java
  • OpenID Connect CIBA Core 1.0 Section 7.1

最終更新: 2025-12-09