一键导入
use-case-external-api-auth
外部API認証ユースケースの設定ガイド。外部API連携(認証委譲、リスク判定、OTP等)の interaction 設計、identity_match_field、MFA 2段階目、previous_interaction のヒアリングと設定JSONを提供。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
外部API認証ユースケースの設定ガイド。外部API連携(認証委譲、リスク判定、OTP等)の interaction 設計、identity_match_field、MFA 2段階目、previous_interaction のヒアリングと設定JSONを提供。
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | use-case-external-api-auth |
| description | 外部API認証ユースケースの設定ガイド。外部API連携(認証委譲、リスク判定、OTP等)の interaction 設計、identity_match_field、MFA 2段階目、previous_interaction のヒアリングと設定JSONを提供。 |
任意の外部APIと連携した認証を、設定JSONだけで構築するユースケース。
/external-api-authentication エンドポイントで、リクエストボディの interaction フィールドにより複数の外部API処理を切り替える。
ユースケース:
| 項目 | external-password-auth | external-api-auth(これ) |
|---|---|---|
| エンドポイント | /password-authentication | /external-api-authentication |
| type | password | external-api-authentication |
| interaction | 1つ固定(password-authentication) | 複数定義可能(interaction フィールドで選択) |
| user_resolve | 必須 | interaction ごとに有無を選択 |
| Challenge-Response | 非対応 | previous_interaction で対応 |
| MFA 2段階目 | 対応 | 対応(identity_match_field による一致検証あり) |
| セキュリティイベント | password_success/failure | external_api_{interaction}_{success/failure}(動的) |
| # | 決めること | 選択肢 | 影響する設定 |
|---|---|---|---|
| 1 | 連携する外部APIのURL | 実サービスURL / モック | 認証メソッド設定 http_request.url |
| 2 | 外部API認証方式 | oauth2 / hmac_sha256 / none | 認証メソッド設定 http_request.auth_type |
| 3 | interaction 設計 | 名前、数、各 interaction の役割 | 認証メソッド設定 interactions キー |
| 4 | user_resolve の有無 | interaction ごとに決定 | 認証メソッド設定 user_resolve |
| 5 | Challenge-Response の要否 | previous_interaction 使用有無 | 認証メソッド設定 http_request_store + previous_interaction |
| 6 | MFA 2段階目で使うか | yes / no | 認証ポリシー step_definitions |
| 7 | identity_match_field | JSONPath($.email, $.phone_number 等)/ 未設定 | 認証メソッド設定 user_resolve.identity_match_field |
| 8 | 認証済みユーザー属性の外部送信 | $.user.* を送るか(送る属性・送信先interaction) | 認証メソッド設定 http_request.body_mapping_rules($.user.*) |
| 9 | セッション有効期限 | 秒数(デフォルト: 86400) | テナント session_config.timeout_seconds |
| 10 | トークン有効期限(AT) | 秒数(デフォルト: 3600) | 認可サーバー extension.access_token_duration |
| ヒアリング項目 | 環境変数 | デフォルト値 |
|---|---|---|
| 外部APIサービスURL | EXTERNAL_API_URL | http://host.docker.internal:4000/auth/password |
| 外部プロバイダー識別子 | EXTERNAL_PROVIDER_ID | external-api |
| 外部API認証方式 | EXTERNAL_API_AUTH_TYPE | none |
| ヒアリング項目 | 環境変数 | デフォルト値 |
|---|---|---|
| セッション有効期限(秒) | SESSION_TIMEOUT_SECONDS | 86400 |
| AT有効期限(秒) | ACCESS_TOKEN_DURATION | 3600 |
| IDT有効期限(秒) | ID_TOKEN_DURATION | 3600 |
| RT有効期限(秒) | REFRESH_TOKEN_DURATION | 86400 |
API: POST /v1/management/organizations/{org-id}/tenants/{tenant-id}/authentication-configurations
{
"type": "external-api-authentication",
"metadata": { "description": "External API authentication" },
"interactions": {
"password_verify": {
"request": {
"schema": {
"type": "object",
"required": ["interaction", "username", "password"],
"properties": {
"interaction": { "type": "string" },
"username": { "type": "string", "minLength": 1 },
"password": { "type": "string", "minLength": 1 }
}
}
},
"execution": {
"function": "http_request",
"http_request": {
"url": "${EXTERNAL_API_URL}",
"method": "POST",
"header_mapping_rules": [
{ "static_value": "application/json", "to": "Content-Type" }
],
"body_mapping_rules": [
{ "from": "$.request_body.username", "to": "username" },
{ "from": "$.request_body.password", "to": "password" }
]
}
},
"user_resolve": {
"identity_match_field": "$.email",
"user_mapping_rules": [
{ "from": "$.execution_http_request.response_body.user_id", "to": "external_user_id" },
{ "from": "$.execution_http_request.response_body.email", "to": "email" },
{ "from": "$.execution_http_request.response_body.name", "to": "name" },
{ "static_value": "${EXTERNAL_PROVIDER_ID}", "to": "provider_id" }
]
},
"response": {
"body_mapping_rules": [
{ "from": "$.execution_http_request.response_body.email", "to": "email" }
]
}
}
}
}
{
"interactions": {
"password_verify": { "...": "(パターンA と同じ)" },
"risk_check": {
"execution": {
"function": "http_request",
"http_request": {
"url": "https://risk.example.com/assess",
"method": "POST",
"body_mapping_rules": [
{ "from": "$.request_body.device_fingerprint", "to": "fingerprint" },
{ "from": "$.user.sub", "to": "user_id" },
{ "from": "$.user.email", "to": "email" }
]
}
},
"response": {
"body_mapping_rules": [
{ "from": "$.execution_http_request.response_body.risk_score", "to": "risk_score" }
]
}
}
}
}
$.user.* で認証済みユーザーの属性を外部APIに渡せる(例: リスク判定に「誰のリスクか」を渡す)。詳細は下記「$.user.* 認証済みユーザーの外部送信」を参照。
{
"interactions": {
"otp_send": {
"execution": {
"function": "http_request",
"http_request": { "url": "https://otp.example.com/send", "method": "POST" },
"http_request_store": {
"key": "otp_send",
"interaction_mapping_rules": [
{ "from": "$.response_body.transaction_id", "to": "transaction_id" }
]
}
}
},
"otp_verify": {
"execution": {
"function": "http_request",
"previous_interaction": { "key": "otp_send" },
"http_request": {
"url": "https://otp.example.com/verify",
"method": "POST",
"body_mapping_rules": [
{ "from": "$.interaction.transaction_id", "to": "transaction_id" },
{ "from": "$.request_body.code", "to": "verification_code" }
]
}
},
"user_resolve": {
"user_mapping_rules": [ "..." ]
}
}
}
}
API: POST /v1/management/organizations/{org-id}/tenants/{tenant-id}/authentication-policies
{
"flow": "oauth",
"enabled": true,
"policies": [
{
"description": "external_api_only",
"priority": 1,
"available_methods": ["external-api", "initial-registration"],
"success_conditions": {
"any_of": [
[{ "path": "$.external-api-authentication.success_count", "type": "integer", "operation": "gte", "value": 1 }],
[{ "path": "$.initial-registration.success_count", "type": "integer", "operation": "gte", "value": 1 }]
]
}
}
]
}
{
"flow": "oauth",
"enabled": true,
"policies": [
{
"description": "password + external API verification",
"priority": 1,
"available_methods": ["password", "external-api", "initial-registration"],
"step_definitions": [
{ "method": "password", "order": 1, "requires_user": false, "user_identity_source": "username" },
{ "method": "external-api", "order": 2, "requires_user": true }
],
"success_conditions": {
"any_of": [
[
{ "path": "$.password-authentication.success_count", "type": "integer", "operation": "gte", "value": 1 },
{ "path": "$.external-api-authentication.success_count", "type": "integer", "operation": "gte", "value": 1 }
],
[{ "path": "$.initial-registration.success_count", "type": "integer", "operation": "gte", "value": 1 }]
]
}
}
]
}
重要: この設定が無いと UserInfo / ID Token が
subのみしか返さない。
PUT /v1/management/organizations/{org-id}/tenants/{tenant-id}/authorization-server で設定。
MFA 2段階目で user_resolve を使う場合、identity_match_field の設定が重要。
| パターン | identity_match_field | 説明 |
|---|---|---|
| メールで一致検証 | $.email | 1st factor のユーザーと email で比較 |
| 外部ユーザーIDで一致検証 | $.external_user_id | provider 間の ID で比較 |
| 電話番号で一致検証 | $.phone_number | 電話番号で比較 |
| カスタムプロパティで一致検証 | $.custom_properties.member_id | 任意のカスタムフィールドで比較 |
| 比較スキップ(リスク判定等) | 未設定 | hasUser チェックのみ |
選び方:
$.user.* 認証済みユーザーの外部送信http_request.body_mapping_rules の from で $.user.* を使うと、認証済みユーザーの属性を外部APIリクエストに含められる(RP が再送する必要がない)。リスク判定・不正検知APIに「誰のリスクか」を渡す用途に最適。
"body_mapping_rules": [
{ "from": "$.user.sub", "to": "user_id" },
{ "from": "$.user.email", "to": "email" },
{ "from": "$.user.custom_properties.member_rank", "to": "rank" }
]
利用可能なタイミング: $.user.* は「トランザクションに認証済みユーザーが既にいる」場合のみ値を持つ。
送信できる属性(allow-list): sub / provider_id / email / phone_number / name / given_name / family_name / middle_name / roles / custom_properties.*。hashed_password / credentials / verified_claims 等の機微情報は送信不可(fail-safe)。各属性は body_mapping_rules で明示的にマッピングした場合のみ送信される。姓名分割を要求する外部API(SEON の user_firstname/user_lastname 等)には $.user.given_name/$.user.family_name を使う。
ヒアリング: 外部APIに認証済みユーザー属性を送りたいか? → はい なら、送る属性(sub/email 等)と送信先 interaction(通常はMFA 2段階目のリスク判定等)を確認。
注意: $.user.roles / $.user.custom_properties は、ユーザーを確立した認証方式に依存する(通常ログイン・login_hint 経由のユーザーは保持、external-api 自体を1段階目としたユーザーは未保持)。ロール依存の分岐は認証ポリシー条件($.user.*)側での判定を推奨。
| ケース | イベント名 |
|---|---|
password_verify 成功 | external_api_password_verify_success |
password_verify 失敗 | external_api_password_verify_failure |
risk_check 成功 | external_api_risk_check_success |
| interaction 未指定 / 未登録 | external_api_authentication_failure |
| # | 確認観点 | よくあるミス |
|---|---|---|
| 1 | claims_supported が設定済み | 未設定で UserInfo/ID Token が sub のみ |
| 2 | EXTERNAL_API_URL が idp-server コンテナから到達可能 | localhost を指定 → host.docker.internal を使う |
| 3 | identity_unique_key_type が EMAIL_OR_EXTERNAL_USER_ID | EMAIL のままだと外部ユーザーIDでの識別が機能しない |
| 4 | MFA 2段階目で identity_match_field が設定済み | 未設定だとフィールド比較がスキップされる |
| 5 | provider_id が static_value で固定値 | 外部APIの値を使うと攻撃者が制御可能 |
| 6 | Challenge-Response で http_request_store.key と previous_interaction.key が一致 | キー不一致でデータ受け渡しが機能しない |
documentation/docs/content_02_quickstart/quickstart-14-external-api-authentication.md - クイックスタートdocumentation/docs/content_05_how-to/phase-4-extensions/06-external-api-authentication.md - 設定ガイド(Step by Step)documentation/docs/content_06_developer-guide/05-configuration/authn/external-api.md - 設定リファレンスuse-case-external-password-auth - 外部パスワード認証委譲(単一 interaction)spec-external-integration - 外部サービス連携の詳細(HTTP Request Executor, MappingRule)spec-authentication - 認証ポリシー・MFA の詳細$ARGUMENTS
UserInfoエンドポイント(UserInfo Endpoint)機能の開発・修正を行う際に使用。UserInfo claims、scopeフィルタリング、verified_claims実装時に役立つ。
ユースケース別セットアップのエントリポイント。ユーザーにユースケースを選択してもらい、対応するスキル(use-case-login, use-case-mfa等)にルーティングする。共通ワークフロー、前提条件、組み合わせパターンの概要を提供。
認証機能(Authentication Policy, MFA)の開発・修正を行う際に使用。認証ポリシー、パスワード、OTP、FIDO2、条件付き認証実装時に役立つ。
セキュリティ・脆弱性対策の開発・テストを行う際に使用。OAuth/OIDC攻撃対策、認証識別子切り替え攻撃、Session Fixation、マルチテナント分離、セキュリティテスト実装時に役立つ。
外部サービス連携(External Service Integration)機能の開発・修正を行う際に使用。HTTP Request Executor, MappingRule, OAuth/HMAC認証実装時に役立つ。
FIDO2/WebAuthn/パスキー関連の実装・設定・ドキュメント・テストを扱う時に使用。パスキー登録、認証、管理、アテステーション検証に関する作業で自動的に呼び出される。