「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
CIBAは、シーバと読み「新たなユーザ認証体験」のベースとなりうるものらしい。
に分離することによりユーザー認証体験の可能性が広がる。
※ OpenID Foundation の MODRNA(マッダーヌァ) WG (mobile系 の WG)で策定。
MODRNA : Mobile Operator Discovery, Registration & autheNticAtion?.
イメージ †
用語 †
- 基本的な用語は、OAuth2/OIDCと変わらない。
Consumption Device (CD) †
CIBA Flow ユーザ(なんでもOK)だが、
基本的にConfidential Client(RP)を経由する。
Authentication Device (AD) †
- 認証デバイス
EndUser?(≒ Resource Owner)の
所有物として認証されているデバイス。
- Publicであるが、Public "Client"ではない。
BA EP(バックチャネル認証エンドポイント) †
フロントエンドからリーチしない
Confidential Client(RP)経由の
バックチャネルと言う事だろうか。
- AuthZ(IdP/STS)に追加される新たな認証エンドポイント。
- AuthZはCDからRP経由で認証リクエストを受付け、
- 非同期で、CDにRP経由で認証レスポンスを返す(Polling / Ping / Push)。
その他、用語の差異 †
- 認可リクエストではなく認証リクエスト
- しかし、AuthZ は AuthZ。AuthNではない。
- Resource Owner ではなく EndUser?(ユーザ)
ユースケース †
以下のようなユースケースがある。
- 銀行窓口での顧客認証
- コールセンタにおける発信者認証
- ユーザのスマホで POS 端末の支払い
ポイント †
CIBAのユースケースのポイントは、
- 認証リクエストする人と、
- スマホの認可 or 拒否ボタンを押下する人が、
違うコトであるもよう。
同一人物の場合 †
- 2FA的な意味合いも無いので微妙。
(CIBAのADを2FAに転用することは可能だが)
認可リクエストを行う人と、認可 or 拒否ボタンを押下する人が違う。
- IdP/STS(OP)にDevice Flow独自エンドポイントに認証リクエストを行う。
- 認証レスポンスから受け取ったURIとCodeを画面に表示する(QRコードやNFCなども利用可能)。
- ユーザは、URIでIdP/STS(OP)に接続し、対話する(認可 or 拒否)。
(仕様に詳しく書かれていないが、AuthZ Serverに追加した画面に認証後にアクセス)
- 上記の後、Device は、TokenリクエストをPollingする。
- CD は、IdP/STS(OP)にCIBA独自バックチャネルに認証リクエストを行う。
- IdP/STS(OP)が AD を用いて要求を認証するユーザにプッシュ通知する。
- ユーザは、プッシュ通知をトリガにして AD に遷移して対話する(認可 or 拒否)。
(仕様に詳しく書かれていないが、PKCEなどで認証処理を行う必要がある)
事前のユーザー識別 †
Clientの、事前のユーザー識別は必要になる。
- CD
- 要求時、Client が IdP/STS(OP)に認証対象ユーザを通知する。
- IdP/STS(OP)は、認証対象ユーザのADを特定 して、プッシュ通知を行う。
- AD
仕様に詳しく書かれていないが、ADでも認証が必要になる。
詳細(フロー) †
フローを見ると、RedirectによるOAuthダンスではなく、OAuth 2.0 Device Flow風で、
デバイスへの通知にSMSではなく、スマホのプッシュ通知を使用している感じの仕様っポイ。
- 従来の従来のOAuthダンスは「Redirect フロー」と言うらしい。
- CIBA は「Decoupled フロー」と言うらしい(decoupled and back-channel)。
認可エンドポイント †
認証リクエストを受け付けて直ちにレスポンスする(以後、非同期的に処理)。
認可リクエスト †
- ユーザ特定が必要になるので、
- クライアントがAuthZの認証リクエストを投げる際、
以下のパラメタのどれか一つをヒントとしてサーバに渡す。
- login_hint_token
- id_token_hint
- login_hint
- サーバはそのヒントを元に認証対象ユーザを特定する。
- scope
- OAuth2.0のscopeと同じ。
- CIBAではopenidスコープ値が含まれている必要がある。
- client_notification_token
- Ping / Pushモードの際のCallback URIに渡すBearer Token
- 1024文字以下(128bit以上で、160bit前後)の乱数を含む自己完結型
- login_hint
エンドユーザーを識別するe-mail、TEL、sub、userName、userIdなど
- login_hint_token
エンドユーザーを識別するためのトークン
(署名が必要≒JWS)
- id_token_hint
エンドユーザーを識別するためのIDトークン
(JWS or JWEでissとaudを検証、期限切れも処理)
- requested_expiry (OPTIONAL)
auth_req_idのexpires_in値を要求できるようにする正の整数。
- Requestオブジェクト
別途、iss, aud, exp, iat, nbf, jtiの追加が必要(JWSのみでJWEはサポートされない)。
{
"iss": "s6BhdRkqt3",
"aud": "https://server.example.com",
"exp": 1537820086,
"iat": 1537819486,
"nbf": 1537818886,
"jti": "4LTCqACC2ESC5BWCnN3j58EnA",
"scope": "openid email example-scope",
"client_notification_token": "8d67dc78-7faa-4d41-aabd-67707b374255",
"binding_message": "W4SCT",
"login_hint_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
認可レスポンス †
- auth_req_id
- 必須。
- プッシュ通知 → 認証ボタン押下を識別するトランザクション識別子。
- 1024文字以下(128bit以上で、160bit前後)の乱数を含む自己完結型
- expires_in
- 必須
- auth_req_id、user_codeの有効期間(秒)。
- 認証デバイスに飛んできた認証要求が
正当なものかどうかを確認するためのパラメタを返す。
- binding_message (OPTIONAL)
・かなり短い単純な文字列であることが想定されている。
・Biding MessageをCDとADの画面に「表示」する。
・比較的短く、プレーンテキスト文字の限られたセットを使用する
- user_code (OPTIONAL)
・未認証状態で送信可能なプッシュ通知技術のために用意されている。
・認証状態でのみ利用可能なプッシュ通知の場合、使用しないを選択可能。
・backchannel_user_code_parameterがtureの場合、configとして必須となる。
・ADのプッシュ通知に表示し、応答で入力させる。
エラーの返却 †
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"error":"missing_user_code"
}
通知->認証 †
通知 †
特定した認証対象ユーザのスマホにプッシュ通知を送信する。
- binding_messageを表示する。
- CDから指定された場合は、user_codeを入力させる。
認証 †
PKCE認証などして、認可 or 拒否ボタン押下で、結果をIdP/STS(OP)に伝える(?)
Tokenエンドポイント †
- 上記の識別子を使用してTokenリクエストする。
- これにより、認証リクエストの結果とTokenレスポンスを返す。
- 認証リクエストとの繋がりは非同期的なので、以下の、Polling / Ping / Pushの3つの方式がある。
Tokenリクエスト †
- 概要
- 認可リクエストの成功を確認した後、TokenリクエストのPolling / Pingを始める。
- Pushの場合は、Pushをトリガにして、動き出す(しかし、結局、Client 側は待機している)。
- パラメタ
- grant_type=urn:openid:params:grant-type:ciba
- auth_req_id
Tokenレスポンス †
- 成功
OIDCの認可レスポンス(成功)と同じ。
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token": "G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN",
"token_type": "Bearer",
"refresh_token": "4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16",
"expires_in": 3600,
"id_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
- authorization_pending
認可リクエストは保留中
- slow_down
"authorization_pending"の変形で
Polling間隔を5秒遅らせろの意味。
- access_denied
Resource Owner(EndUser?)は、承認要求を拒否。
- expired_token
auth_req_id、user_codeの有効期限が切れた。
- unauthorized_client
PushモードのためCIBAでのTokenリクエストは不可。
ポイント †
- 以下の失敗のレスポンスを受け取り、Bearerが、
無効な場合、HTTP 204 No Content or HTTP 200 OK をレスポンス。
無効な場合、HTTP 401 Unauthorized をレスポンス。
POST /cb HTTP/1.1
Host: client.example.com
Authorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255
Content-Type: application/json
{
"auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1",
"error": "access_denied" or "expired_token" or "transaction_failed",
"error_description": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
- 成功のレスポンスの後、Client は Tokenリクエストを行いTokenレスポンスを取得する。
- 良く解らないが、Pingで構成されたClientはPollingも可能らしい。
- Tokenレスポンス・ライクなレスポンスが返り、Bearerが、
無効な場合、HTTP 204 No Content or HTTP 200 OK をレスポンス。
無効な場合、HTTP 401 Unauthorized をレスポンス。
POST /cb HTTP/1.1
Host: client.example.com
Authorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255
Content-Type: application/json
{
"auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1",
"access_token": "G5kXH2wHvUra0sHlDy1iTkDJgsgUO1bN",
"token_type": "Bearer",
"refresh_token": "4bwc0ESC_IAhflf-ACC_vjD_ltc11ne-8gFPfA2Kx16",
"expires_in": 3600,
"id_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
- id_tokenを検証する(改ざんされていないか確認)。
urn:openid:params:jwt:claim:auth_req_idの一致と、
at_hashを使用したaccess_token検証
rt_hashを使用したrefresh_token検証
{
"iss": "https://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"email": "janedoe@example.com",
"exp": 1537819803,
"iat": 1537819503,
"at_hash": "Wt0kVFXMacqvnHeyU0001w",
"urn:openid:params:jwt:claim:rt_hash": "sHahCuSpXCRg5mkDDvvr4w",
"urn:openid:params:jwt:claim:auth_req_id":
"1c266114-a1be-4252-8ad1-04986c5b9ac1"
}
- PPIDの利用(subject_type が pairwiseのとき)
- Polling / Pingモード
- PPID計算のセクター識別子としてjwks_uriを使用する。
- 故に、登録フェーズでjwks_uriを提供する必要がある。
- sector_identifier_uriを提示する場合、ココに、jwks_uriを含める。
- jwks_uriの妥当性はクライアント認証を用いることで検証可能。
- Pushモード
- PPID計算のセクター識別子としてbackchannel_client_notification_endpointを使用する。
- sector_identifier_uriを提示する場合、ココに、backchannel_client_notification_endpointを含める。
- jwks_uri異なり、backchannel_client_notification_endpointの妥当性検証は不要。
その他 †
メタデータ †
- grant_types
grant_types_supported に urn:openid:params:grant-type:ciba を追加。
- 認可エンドポイント
backchannel_authentication_endpoint を追加。
- 非同方式
backchannel_token_delivery_modes_supported : ["poll", "ping", "push"]
- 認可リクエストの署名アルゴリズム
backchannel_authentication_request_signing_alg_values_supported
- user_codeのサポートの有・無(デフォルト値はfalse)
backchannel_user_code_parameter_supported
- 非同方式
backchannel_token_delivery_mode : "poll" or "ping" or "push"
- PingまたはPushの際のCallbackエンドポイント
backchannel_client_notification_endpoint
- 認可リクエストの署名アルゴリズム(既定値は署名無し)
backchannel_authentication_request_signing_alg
- user_codeのサポートの有・無(デフォルト値はfalse)
backchannel_user_code_parameter
- 登録の例
POST /connect/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ ...
{
"application_type": "web",
"client_name": "My Example",
"logo_uri": "https://client.example.org/logo.png",
"subject_type": "pairwise",
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": ["urn:openid:params:grant-type:ciba"],
"backchannel_token_delivery_mode": "poll",
"jwks_uri": "https://client.example.org/my_public_keys.jwks",
"userinfo_encrypted_response_alg": "RSA1_5",
"userinfo_encrypted_response_enc": "A128CBC-HS256",
"contacts": ["ve7jtb@example.org", "mary@example.org"]
}
セキュリティ考慮事項 †
- PPIDを含むIDトークン
使用可能である模様(確かにclient_idでPPID計算のセクター識別子を特定可)。
- 使い捨てユーザーID
ADで認証後にIDを生成し、QRコードでCDにlogin_hint_tokenを転送
- ディスカバリー・サービス
RPがユーザーをディスカバリサービスからlogin_hint_tokenを受信
- FAPI-CIBA プロファイルという新仕様がUK OBIEから寄付(2019 年 8 月に承認)。
- プロファイルは、読み取り専用APIと読み取り/書き込みAPIの両方に適用される。
要約 †
AuthN Server †
- FAPI-CIBA プロファイルを使えるのはConfidential Clientのみ。
- 認可リクエスト
- JARを使用する。
- nbf クレームと exp クレームを含む。
- JWT の生存期間は 60 分以内。
- PPIDについては(、redirect_uriが無いので)、request_uri(URN)を使う?
...その場合、URNのヘッダ部分をClient毎に固定する必要があるかもしれない。
(そもそもCIBAは外部ログインには使用しないので、匿名になりさえすれば良さそう)
(また、そもそもCIBAするClientは、名寄せなどを行わなそうなのでPPIDも不要かも。)
- request_context パラメーターが含まれることを要求してもよい。
- 詐欺や脅威の決定を知らせるJSONオブジェクト(内容は仕様で定義されていない)。
- 例:CDに位置情報を提供するために、信頼関係者が必要になる場合がある。
- login_hint や login_hint_token を流用してはならない。
(流用とは、例えば、この項目を下記の意図(intent)に使用するなど。)
- 複雑な認可パラメタを伝える場合、"lodging intent"パターンを考慮する。
例えば、アクセスの範囲(scope)ではなくて、意図(intent)を指定する。
(intentは、PARやRARで指定するとのことだが、ココではPARになる)。
- 非同期方式
- Pollingモードをサポートしなければならない
- Pushモードをサポートしてはならない
- Pingモードをサポートしてもよい
- 以下の何れかが必須
- 認可コンテキストが一意(抽象的)
- binding_messageが必須(具体的)
Client †
- CD
- CDは、下記ヘッダを送信してはならない
- x-fapi-auth-date
- x-fapi-consumer-ip-address
セキュリティ考慮事項 †
- login_hint や login_hint_token
- login_hintに広く知られている識別子(電話番号など)使用される場合のリスク
- login_hint_tokenはチャネルに適切であることを確認する必要がある。
- binding_messageに加え、
(必要に応じて)user_code パラメタも使用した方がイイ。
- JWT署名
- ES256 と PS256のみ許可
- RSA1_5(≒ RSXXX)は禁止
- TLS
暗号スイートの許可リストに含めるべき。
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
参考 †
内部 †
外部 †
OpenID †
TakahikoKawasaki? †
tkudo †
ritou †
- OIDC Client Initiated Backchannel Authentication Flow (CIBA)とは
OSSコンソーシアム †
開発基盤部会 Blog †
Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth
|