Client Initiated Backchannel Authentication(CIBA)
Client Initiated Backchannel Authentication(CIBA) 是 OpenID Connect 的擴展規範,定義了一種不依賴瀏覽器重導的身分驗證流程。
解決什麼問題
Section titled “解決什麼問題”傳統的 OpenID Connect 流程都依賴瀏覽器重導——使用者在同一台裝置上被導向 OP 登入,再導回 RP。這在很多場景下行不通:
- 銀行櫃檯——行員在自己的電腦操作,需要客戶在手機上授權
- 客服中心——客服需要驗證來電者身分,但來電者不在電腦前
- POS 結帳——收銀台的系統需要顧客用手機授權付款
- 受限裝置——租借腳踏車站、零售 Kiosk 等無法開瀏覽器的裝置
這些場景的共通點是:發起請求的裝置和使用者進行身分驗證的裝置不是同一台。CIBA 的解法是讓 RP 透過 back-channel 直接與 OP 通訊,OP 再通知使用者在另一台裝置(通常是手機)上完成驗證。
與 Device Authorization Grant 的比較
Section titled “與 Device Authorization Grant 的比較”Device Authorization Grant 也解決「跨裝置授權」的問題,但兩者的設計目標不同:
| Device Authorization Grant | CIBA | |
|---|---|---|
| 使用者識別 | 不需要——使用者自行輸入 user code | 需要——RP 必須提供使用者的識別資訊 |
| 通訊方向 | 裝置輪詢 AS,使用者主動造訪授權頁面 | RP 直接通知 OP,OP 主動推送給使用者 |
| 典型場景 | Smart TV、遊戲主機(使用者在裝置前) | 銀行櫃檯、客服中心(使用者不在發起裝置前) |
| Token 取得 | 只有輪詢 | Poll、Ping、Push 三種模式 |
簡單來說:Device Authorization Grant 是「使用者在裝置前,但裝置輸入不方便」;CIBA 是「使用者可能根本不在發起請求的裝置前」。
兩個裝置的概念
Section titled “兩個裝置的概念”CIBA 引入了兩個裝置的區分:
| 裝置 | 角色 | 範例 |
|---|---|---|
| Consumption Device | 使用者與 RP 互動的裝置 | 銀行行員的電腦、POS 機、Kiosk |
| Authentication Device | 使用者進行身分驗證的裝置 | 使用者的手機 |
RP 在 Consumption Device 上發起請求,使用者在 Authentication Device 上完成驗證——兩者之間的關聯由 OP 負責串接。
sequenceDiagram
participant RP as Relying Party<br>(Consumption Device)
participant OP as OpenID Provider
participant User as 使用者<br>(Authentication Device)
RP->>OP: 1. Backchannel Authentication Request
OP->>RP: 2. 回傳 auth_req_id
OP->>User: 3. 推送驗證通知
User->>OP: 4. 使用者完成驗證並授權
alt Poll 模式
loop 輪詢
RP->>OP: 5a. Token Request(帶 auth_req_id)
OP-->>RP: authorization_pending
end
OP->>RP: 核發 Token
else Ping 模式
OP->>RP: 5b. 通知 RP(帶 auth_req_id)
RP->>OP: Token Request
OP->>RP: 核發 Token
else Push 模式
OP->>RP: 5c. 直接推送 Token
end
Step 1:Backchannel Authentication Request
Section titled “Step 1:Backchannel Authentication Request”RP 向 OP 的 Backchannel Authentication Endpoint 發送請求:
POST /bc-authorize HTTP/1.1Host: op.example.comContent-Type: application/x-www-form-urlencoded
scope=openid%20profile&binding_message=ABCD1234&client_notification_token=8d67dc78-7faa-4d41-aabd-67707b374255| 參數 | 必要性 | 說明 |
|---|---|---|
scope | REQUIRED | 必須包含 openid |
login_hint | 三擇一 | 使用者的識別資訊(如 email、電話號碼) |
id_token_hint | 三擇一 | 先前核發的 ID Token,用於識別使用者 |
login_hint_token | 三擇一 | 已簽署的 Token,包含使用者識別資訊 |
binding_message | OPTIONAL | 顯示在兩台裝置上的關聯訊息(見下方說明) |
user_code | OPTIONAL | 使用者的 PIN 或密碼,防止未經請求的通知 |
client_notification_token | Ping/Push 必要 | OP 回呼 RP 時使用的 Bearer Token(至少 128 bits 熵) |
acr_values | OPTIONAL | 偏好的身分驗證等級 |
requested_expiry | OPTIONAL | 希望 auth_req_id 的有效期(秒) |
RP 必須提供 login_hint、id_token_hint、login_hint_token 其中一個(且只能一個),讓 OP 知道要驗證的是哪位使用者。
Step 2:Authentication Response
Section titled “Step 2:Authentication Response”OP 確認請求有效後,回傳確認回應:
{ "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1", "expires_in": 120, "interval": 5}| 欄位 | 必要性 | 說明 |
|---|---|---|
auth_req_id | REQUIRED | 這次驗證請求的唯一識別碼(至少 128 bits 熵) |
expires_in | REQUIRED | auth_req_id 的有效期(秒) |
interval | OPTIONAL | Poll 模式下的最小輪詢間隔,預設 5 秒 |
Step 3–4:使用者驗證
Section titled “Step 3–4:使用者驗證”OP 透過自己的機制(推播通知、SMS 等)通知使用者的 Authentication Device。使用者在手機上看到驗證請求,確認後完成身分驗證與授權。
如果 RP 有提供 binding_message,使用者的手機上會顯示這段訊息(例如 ABCD1234),使用者可以對照 Consumption Device 上顯示的同一組訊息,確認兩邊是同一筆交易。
Step 5:取得 Token
Section titled “Step 5:取得 Token”根據 RP 註冊時選擇的模式,有三種方式取得 Token:
Poll 模式
Section titled “Poll 模式”RP 定期向 Token Endpoint 輪詢:
POST /token HTTP/1.1Host: op.example.comContent-Type: application/x-www-form-urlencoded
grant_type=urn:openid:params:grant-type:ciba&auth_req_id=1c266114-a1be-4252-8ad1-04986c5b9ac1使用者尚未完成時回傳 authorization_pending,輪詢太頻繁回傳 slow_down(與 Device Authorization Grant 相同的錯誤碼)。
Ping 模式
Section titled “Ping 模式”OP 在使用者完成後,向 RP 註冊的 backchannel_client_notification_endpoint 發送通知:
POST /ciba-notification HTTP/1.1Host: rp.example.comAuthorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255Content-Type: application/json
{ "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1"}RP 收到通知後再向 Token Endpoint 請求 Token。
Push 模式
Section titled “Push 模式”OP 直接將 Token 推送到 RP 的通知端點:
POST /ciba-notification HTTP/1.1Host: rp.example.comAuthorization: Bearer 8d67dc78-7faa-4d41-aabd-67707b374255Content-Type: application/json
{ "auth_req_id": "1c266114-a1be-4252-8ad1-04986c5b9ac1", "access_token": "eyJhbGciOiJSUzI1NiJ9...", "token_type": "Bearer", "expires_in": 3600, "id_token": "eyJhbGciOiJSUzI1NiJ9..."}Push 模式下,ID Token 必須包含額外的 hash 值(at_hash、urn:openid:params:jwt:claim:auth_req_id)來防止竄改。
三種模式的比較
Section titled “三種模式的比較”| Poll | Ping | Push | |
|---|---|---|---|
| RP 需要公開端點 | 不需要 | 需要 | 需要 |
| Token 取得方式 | RP 輪詢 Token Endpoint | OP 通知 → RP 再取 Token | OP 直接推送 Token |
| 實作複雜度 | 低 | 中 | 高 |
| 即時性 | 取決於輪詢間隔 | 高 | 最高 |
client_notification_token | 不需要 | 需要 | 需要 |
binding_message 的顯示限制
Section titled “binding_message 的顯示限制”binding_message 是讓使用者確認「兩台裝置上看到的是同一筆交易」的機制。但規範要求它必須簡短且使用有限的純文字字元,因為它要在各種裝置上顯示(手機推播、SMS 等)。這代表它能攜帶的資訊有限,無法完整描述交易內容。
user_code 的使用者體驗代價
Section titled “user_code 的使用者體驗代價”user_code 可以防止使用者收到未經請求的驗證通知——只有知道使用者 PIN 的 RP 才能發起請求。但這代表使用者每次都要輸入 PIN,增加了操作步驟。並非所有 OP 都支援此參數。
Push 模式的安全與複雜度
Section titled “Push 模式的安全與複雜度”Push 模式最即時,但也最複雜:RP 必須驗證 ID Token 中的 hash 值、確保通知端點的安全、處理 Token 被攔截的風險。規範建議 Push 模式應使用 sender-constrained access token 來降低 Token 被攔截後濫用的風險。
login_hint_token 的簽署
Section titled “login_hint_token 的簽署”如果使用 login_hint_token 來識別使用者,規範要求它必須經過數位簽署,以防止攻擊者注入偽造的識別資訊、冒充其他使用者發起驗證。
通知端點的驗證
Section titled “通知端點的驗證”OP 應確認 RP 註冊的 backchannel_client_notification_endpoint 確實屬於該 RP 的管理範圍,避免 Token 被送到錯誤的接收端。
未經請求的驗證通知
Section titled “未經請求的驗證通知”沒有 user_code 機制時,任何知道使用者識別資訊(如 email)的 RP 都能觸發驗證通知推送到使用者的手機上。這可能被濫用為騷擾手段,或透過疲勞攻擊(notification fatigue)誘騙使用者不小心同意授權。user_code 是主要的防禦措施。
Push 模式的 Token 竄改
Section titled “Push 模式的 Token 竄改”Push 模式下,Token 透過網路直接傳送到 RP 的端點,有被中間人攔截或竄改的風險。規範要求 ID Token 必須包含 at_hash(Access Token hash)與 urn:openid:params:jwt:claim:auth_req_id(請求 ID),讓 RP 能驗證 Token 的完整性。