搜尋文件

輸入關鍵字,搜尋標題與正文。

    API文件 07/16

    身分驗證與授權

    本文提要

    知道呼叫者是誰,與允許他讀取哪一篇文章,是兩個不同問題。 API 即使已確認一個帳號登入成功,仍須判斷這個主體能否對目標資源執行目前的操作。

    文件與本文目錄
    本主題文件

    知道呼叫者是誰,與允許他讀取哪一篇文章,是兩個不同問題。 API 即使已確認一個帳號登入成功,仍須判斷這個主體能否對目標資源執行目前的操作。

    本文從身分、資源與操作的關係說起,再區分憑證、token、OAuth 與 OpenID Connect。 先備概念可讀〈介面、契約與責任〉; 本文是基礎概念說明,不指定應採用的登入產品、權限框架或憑證設定方式。

    查證日期:2026-11-02。依據 RFC 6749、RFC 6750(均為 2012 年 10 月), OpenID Connect Core 1.0 incorporating errata set 2(2023-12-15),以及查證當日的 OWASP Cheat Sheets。 RFC 與 OIDC 版本在此用於概念定義,不是完整的現行部署指南;OWASP 網頁持續更新。 本文只查閱文件,未建置登入、發送測試請求、執行服務或進行攻擊測試;文章案例均為自創。

    身分驗證回答「誰」,授權回答「可不可以」

    身分驗證(authentication)確認某個實體的身分; 授權(authorization)判斷特定實體提出的操作或服務要求是否被允許。 前者成功不會自動推出後者成功。 參考 OWASP Authorization:Introduction。

    接受判斷的主體(subject/principal)可以是人的帳號,也可以是服務程式的身分。 例如背景整理程式以自己的權限讀取資料,不必假設每次呼叫背後都有一個正在操作畫面的使用者。 OAuth 2.0 也區分代表資源擁有者取得存取權,以及應用程式代表自身取得存取權的情境。 參考 RFC 6749 摘要。

    閱讀授權規則時,可以把判斷拆成四項:

    表格・2 欄 4 列
    項目自創文章服務中的例子
    主體已確認身分的讀者甲、讀者乙,或某個服務帳號
    資源(resource)某一篇文章,而不是只有「文章 API」這個大類
    操作(action)讀取、修改、刪除;獲准其中一項不代表全部獲准
    情境(context)文章是否公開、誰擁有它,以及政策需要的其他可信資訊

    這是本文整理政策的閱讀方式,不是要求每個系統都設置四個同名欄位。 權限可能依角色、屬性或主體與資源的關係決定;應依實際政策說明判斷依據, 不能只看到「已登入」或某個角色名稱就補上未授予的能力。 參考 OWASP Authorization:屬性與關係。

    用公開與私人文章看物件權限

    以下另設一個假想文章服務:公開文章任何人可讀;私人文章只有擁有者可讀。 已確認身分的擁有者可修改自己的文章,其他人不可修改。本例不討論分享、管理員與刪除功能。 這是教學政策,不是 CarlAcademy 的產品存取政策,也不沿用前篇文章服務未定義的規則。

    表格・4 欄 3 列
    主體讀公開文章 A(甲擁有)讀私人文章 B(甲擁有)修改 A 或 B
    未驗證身分的訪客允許拒絕拒絕
    已驗證的讀者甲允許允許允許
    已驗證的讀者乙允許拒絕拒絕

    甲、乙都有「讀者」角色,卻不能因此讀取同一批私人文章。 判斷 B 時還需要「B 的擁有者是否為目前主體」這項關係。 乙登入成功,只解決身分問題;把目標從乙自己的文章改成 B,不會得到甲的權限。

    物件識別碼無論是容易猜到的數字,或較難猜的隨機值,都需要相應的存取檢查。 較難猜不等於已授權;知道某個 ID 也不等於擁有它。 OWASP 將缺少物件存取檢查造成的問題稱為不安全的直接物件參照(IDOR), 並強調複雜識別碼不能取代檢查。 參考 OWASP:Insecure Direct Object Reference Prevention。

    提供者在可信任邊界執行判斷

    權限必須在每次請求得到正確檢查,並在提供者可控制的可信任邊界落實,例如伺服器或受控閘道。 畫面隱藏按鈕能改善使用體驗,卻不能取代該檢查;用戶端提供的「我是擁有者」也不能自行成為證據。 OWASP 建議最小權限(least privilege)、預設拒絕(deny by default),並驗證每次請求的權限。 前者只授予完成工作所需的能力;後者在沒有明確允許依據時拒絕,而非自動放行。 參考 OWASP Authorization:Recommendations。

    對前述例子,讀 B 前需使用可信的主體與文章歸屬資料判斷;修改也需檢查修改權限。 登入過一次、曾讀取 A,或從某個畫面走到這裡,都不構成讀 B 的許可。 這是依案例政策推演的結果,不要求每次重新輸入密碼;身分驗證狀態可以依所用機制延續。

    「每次檢查」也不表示每個方法都各寫一套規則。 檢查可以由共用機制執行,但它仍須涵蓋受保護的入口、操作與目標物件,並確保受保護資料或操作不會在拒絕前先被放行。 這是從授權應在可信任位置落實推得的要求;實際分工仍依系統邊界而定。 參考 OWASP Authorization:檢查位置。

    憑證、token 與 API key 不是同一種承諾

    憑證(credentials)是用來支持驗證或存取要求的資料;token 則要連同發行者、用途與使用規則理解。 看到一串值被稱為 token,還不足以知道它代表誰、能做什麼,或何時失效。 例如 OAuth access token 本身就是用來存取受保護資源的憑證。 參考 RFC 6749 §1.4。

    API key 常用來識別或管理呼叫端的使用,例如用量或方案;它代表人、應用程式還是專案,要讀提供者契約。 不能只因 key 被接受,就推定持有者可以讀取任意私人文章。 OWASP 也提醒,不應只依賴 API key 保護敏感、關鍵或高價值資源。 參考 OWASP REST Security:API Keys。

    OAuth 與 OIDC 各自處理什麼

    OAuth 2.0 是授權框架,讓應用程式取得受限制的 HTTP 資源存取權。 它本身不是供應用程式確認終端使用者登入身分的協定;RFC 6749 將這項驗證排除在自己的範圍外。 OpenID Connect(OIDC)在 OAuth 2.0 上增加身分層,讓用戶端依提供者的驗證結果確認終端使用者身分。 參考 RFC 6749 §10.16與 OIDC Core 1.0:Introduction。

    表格・3 欄 2 列
    項目主要用途不應直接推定
    access token讓用戶端向資源服務提出獲授權的存取要求這就是給登入用戶端使用的身分證明,或可存取所有物件
    ID token在 OIDC 中向登入用戶端傳達使用者驗證相關的 claims(宣告)這就是可拿去呼叫任意 API 的 access token

    OIDC 的 ID token 有預期接收者;接收端須依規範驗證,而不是只讀出帳號便視為登入成功。 兩種 token 的用途不能因為都由同一次登入過程取得,就任意互換。 參考 RFC 6749 §1.4與 OIDC Core:ID Token。

    OAuth 的 scope 表達獲授權的存取範圍,其名稱由授權服務定義;請求的範圍也不一定全部獲准。 假設某服務定義 articles:read,還要讀它如何結合文章歸屬與公開性,不能自行解讀成「讀任何文章」。 token 的有效期間與允許範圍須以該服務政策、實際核發資訊及適用規範為準,沒有本文統一指定的秒數。 參考 RFC 6749 §3.3與 §5.1。

    bearer 的持有與 JWT 的可讀,都不等於無條件信任

    Bearer token 的特性是持有者即可用它提出相應存取要求,不必另外證明持有某把密碼學金鑰。 因此需要保護它在儲存與傳輸時不被揭露;RFC 6750 的 HTTP 用法要求使用 TLS,通常以 HTTPS 承載。 本文不提供可用憑證;也不能把 token 當成可以任意放進 URL、紀錄或公開範例的普通識別碼。 參考 RFC 6750 摘要與 §1及 §5。

    並非所有 token 都是 JWT;OAuth access token 可以是不供用戶端解讀的值,也可以包含可驗證資訊。 JWT 是一種承載 claims 的格式。能解碼讀出內容,不等於已驗證完整性、發行者、接收對象或期限; 即使這些檢查通過,資源服務仍須確認本次操作的權限,不能跳過前述文章 B 的判斷。 參考 RFC 6749 §1.4與 OWASP REST Security:JWT。

    拒絕結果是表達,不是防護本身

    HTTP API 可能以 401、403,或在適當情況以 404 表達身分與存取問題; 它們的語意及必要標頭見〈狀態碼與錯誤表示〉。 這不是所有 API 必須使用 HTTP 的要求,也不能把錯誤碼當成授權檢查本身。

    依本文案例政策,乙讀私人文章 B 被拒絕時,不能同時把 B 的受保護內容送給乙; 修改被拒絕時,也不能先修改再附上一個拒絕訊息。 這些是從「不允許讀取/修改」推得的可觀察行為,可依〈API 測試〉的方式檢查。 只驗證畫面沒有按鈕、URL 難猜,或 token 有效,都不足以證明授權正確。

    相關文件