iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0

前言

上一篇結尾提到,LDAP 與 Kerberos 撐起了企業內部「身份資料存哪裡、怎麼查」跟「怎麼證明我是這個人」兩個問題,但這兩套協定都是企業內部網路的產物,沒辦法很好地解決「第三方應用程式要怎麼在使用者不透露密碼的前提下,存取另一個服務上的資料」這個 Web 時代才冒出來的新問題——這正是 Day04 提過的 OAuth 想解決的事。這篇要先回到 OAuth 最早的版本 OAuth 1.0:它是怎麼被設計出來的、實際運作起來是什麼樣子、又面臨了哪些限制與挑戰,最後才讓整個社群決定重新設計出 OAuth 2.0

今天內容涵蓋:

  1. OAuth 1.0 的起源與歷史
  2. OAuth 1.0 的角色與核心名詞
  3. OAuth 1.0 的運作方式:三腳授權流程
  4. OAuth 1.0 的簽章機制
  5. OAuth 1.0 的痛點
  6. 為什麼會被 OAuth 2.0 取代

一、OAuth 1.0 的起源與歷史

OAuth 的故事始於 2006 年 11 月,當時 Twitter 跟 Ma.gnolia(一個社群書籤服務)都想讓使用者安全地把第三方應用程式串接到自己的帳號,但當時還沒有一套開放標準能解決這個問題——這個缺口促成了一群開發者開始討論解法。

2007 年 4 月,一個小型的 OAuth 討論社群成立,開始草擬這套開放協定;同年 7 月完成初版規格。2007 年 10 月 3 日,OAuth Core 1.0 正式定稿發布。

2008 年 11 月,在 IETF 第 73 次會議上舉辦了一場 OAuth 的 Birds-of-a-Feather 討論,會後決定在 IETF 內成立正式的 OAuth 工作小組,把這個協定帶入標準化流程。不過在那之前,2009 年 4 月,OAuth 1.0 被發現有一個 Session Fixation(工作階段固定) 的安全性漏洞,影響的正是接下來會介紹的三腳授權流程,社群因此發布了修正過的 OAuth 1.0a(Revision A)。這個修正後的版本,最終在 2010 年 4 月以 RFC 5849 的形式發布——但要注意,RFC 5849 只是「Informational(參考性)」文件,並不是標準路徑(Standards Track)規格,單純是把社群已經在用的協定整理成正式文件備查。

💡 文中提到的 OpenID,是約 2005 年出現的早期身分驗證協定,和前面提到的 OpenID Connect(OIDC) 並不是同一套協定。

OIDC 於 2014 年正式標準化,建立在 OAuth 2.0 之上,主要用來處理使用者身分驗證與身分資訊交換。

從用途上來看,OIDC 可以視為接替了舊版 OpenID 所扮演的角色,但兩者的協定設計、流程與技術實作其實完全不同。


二、OAuth 1.0 的角色與核心名詞

OAuth 1.0 的原始規格(OAuth Core 1.0)使用一套名詞,後來 RFC 5849 把它們重新命名,兩邊常常混用,這裡先對照一次:

原始社群名詞 RFC 5849 名詞 說明
Consumer client 想存取使用者資料的第三方應用程式
Service Provider server 提供資源、同時處理授權的服務(OAuth 1.0 裡兩者通常是同一台伺服器)
User resource owner 擁有資料的使用者本人
Consumer Key + Secret client credentials 用來識別、驗證第三方應用程式身份的一組金鑰
Request Token + Secret temporary credentials 授權流程中代表「這次存取請求」的臨時憑證
Access Token + Secret token credentials 授權完成後,用來實際存取受保護資源的憑證

除了上面這些身份與憑證相關的名詞,簽名請求裡還會帶上幾個關鍵參數,包括 oauth_signature_method(簽章演算法)、oauth_timestampoauth_nonce(合稱用來防止重放攻擊)、oauth_verifier(證明使用者完成授權的驗證碼),這些會在後面分別看到它們實際的用途。


三、OAuth 1.0 的運作方式:三腳授權流程

OAuth 1.0 因為牽涉到三個角色(Client、Resource Owner、Server),協定裡把整個授權過程稱為三腳流程(Three-legged Flow),可以概括成三個大階段、共八個步驟:

https://ithelp.ithome.com.tw/upload/images/20260914/201819288nqmxT7Xpt.png

  1. 取得臨時憑證(Temporary Credentials / Request Token):Client 帶著自己的 Consumer Key、Consumer Secret,對 Server 的 Request Token 端點發一個已簽名的請求,Server 驗證通過後回傳一組尚未授權的 oauth_tokenoauth_token_secret
    • Client → Server:帶 Consumer Key、Consumer Secret,送出已簽名請求,請求 Request Token。
    • Server → Client:回傳未授權的臨時憑證(oauth_token + oauth_token_secret)。
  2. 取得資源擁有者授權(Resource Owner Authorization):Client 把 Resource Owner(使用者)導向 Server 的授權頁面,並帶上剛拿到的臨時憑證;使用者登入 Server 並同意授權後,Server 會透過事先約定的 Callback URL,把使用者導回 Client,同時附上一個 oauth_verifier,證明使用者確實完成了授權這個步驟。
    • Client → Resource Owner:帶上 Request Token,導向授權頁。
    • Resource Owner → Server:登入並同意授權。
    • Server → Client:透過 Callback URL 帶回 oauth_verifier
  3. 交換正式的存取憑證(Token Credentials / Access Token):Client 拿著臨時憑證與 oauth_verifier,再對 Server 的 Access Token 端點發一次已簽名的請求,交換成正式的 oauth_token(Access Token)與 oauth_token_secret;之後 Client 就能拿這組正式憑證,對受保護的資源發出已簽名的請求,取得資料。
    • Client → Server:帶 Request Token + oauth_verifier,交換 Access Token。
    • Server → Client:回傳正式的 oauth_token + oauth_token_secret
    • Client → Server:使用 Access Token 簽署 API 請求,存取受保護的資源。

可以看到,OAuth 1.0 的每一次關鍵請求幾乎都要帶著簽章。下一節就來看這個簽章機制實際上怎麼運作。


四、OAuth 1.0 的簽章機制

OAuth 1.0 選擇不直接把 Token 當密碼一樣裸傳,而是要求 Client 對「每一個」請求都算出一個簽章(Signature),附在請求裡讓 Server 驗證。這麼做的好處是:即使請求在傳輸過程中被截獲,沒有對應的金鑰資訊,也很難偽造出合法的簽章。

一個已簽名的請求,通常會帶上以下幾個關鍵參數:

  • oauth_consumer_key:識別是哪個應用程式(Client)在發請求。
  • oauth_token:目前使用的臨時憑證或存取憑證。
  • oauth_signature_method:簽章演算法,最常見的是 HMAC-SHA1,規格上也支援 RSA-SHA1、PLAINTEXT 等方法。
  • oauth_timestamp / oauth_nonce:時間戳記與隨機字串,用來防止重放攻擊(Replay Attack)。
  • oauth_signature:實際的簽章值。

簽章的計算方式,是把 HTTP 方法、請求網址、所有請求參數,依照規格排序、編碼後串成一段「簽章基礎字串(Signature Base String)」,再用 Consumer Secret 跟 Token Secret 組成的金鑰,對這段字串做雜湊運算(例如 HMAC-SHA1)。Server 收到請求後,會用同樣的方式自己算一次簽章,只要跟請求裡帶的簽章一致,就代表請求沒有被竄改,而且真的是持有正確金鑰的 Client 發出的。

OAuth 1.0 的安全性有很大一部分是靠這套簽章機制撐起來的。這和 OAuth 2.0 把大部分傳輸安全責任交給 HTTPS 的思路不同,也和時代背景有關:2007 年前後 HTTPS 還沒普及,OAuth 1.0 不能假設傳輸層一定加密,因此改由應用層自行以簽章機制確保安全性。


五、OAuth 1.0 的問題

  • 簽章機制的正確性難以確保:每個請求都要照規格把參數排序、百分號編碼、拼出簽章基礎字串,任何一個字元編碼錯了、參數順序不對,簽章就會驗證失敗——即使十幾年後的今天,還是有專門的 API 工具(例如 Bruno)特別做了完整的 RFC 5849 支援,來自動處理這整套簽章邏輯,可見手動處理有多容易出錯。
  • 授權流程種類太少、太固定:OAuth 1.0 原本只針對「網站」場景設計,只有這裡介紹的三腳流程一種主要模式,沒辦法很好地覆蓋原生行動應用程式(Native App)、伺服器對伺服器(Server-to-Server)、IoT 裝置等後來才大量出現的使用情境。
  • 工作階段固定風險:前面提到 2009 年被發現的 Session Fixation 漏洞,就是攻擊者可以搶先取得一組臨時憑證,誘騙使用者用這組憑證完成授權,之後攻擊者就能拿著已授權的臨時憑證去換取 Access Token,間接冒充使用者

💡 OAuth 1.0a 修正版加入了 oauth_verifier 參數,用來補強原本 OAuth 1.0 授權流程中的安全性問題。

  • 金鑰管理負擔重:Client 端要妥善保存 Consumer Secret、Token Secret,而且每次請求都要正確地做簽章運算,對開發者來說實作、除錯成本都不低;PLAINTEXT 簽章方法如果沒有搭配 HTTPS,更是直接把金鑰暴露在網路上。
  • 擴充性不足:OAuth 1.0 沒有內建 Refresh Token 的概念,存取憑證一旦核發,若非長期有效,就必須由使用者重新完整執行一次整套授權流程,很難優雅地處理「短時間存取權杖 + 定期換新」這種現代常見的安全性設計。

六、為什麼會被 OAuth 2.0 取代

IETF 從更廣的社群蒐集使用情境與擴充需求後,決定重新設計一套協定,這就是 OAuth 2.0。它雖然承接 OAuth 1.0 的實務經驗,但並不向下相容,等於是一次全新設計。OAuth 2.0 最終在 2012 年 10 月以 RFC 6749(核心框架)與 RFC 6750(Bearer Token 用法)發布,而且都是標準路徑(Standards Track)規格。

整體而言,OAuth 2.0 主要在幾個方向上做了取捨:

  • 放棄強制的請求簽章,改用 Bearer Token + HTTPS:OAuth 2.0 不再要求每個請求都計算簽章,而是把 Access Token 當成「持有即可用」的 Bearer Token,並把傳輸安全交給 HTTPS,降低實作與除錯的複雜度。
  • 授權流程從 3 種擴充到 6 種以上(Grant Types):針對不同的應用場景(網站、原生 App、伺服器對伺服器、裝置等)提供不同的授權方式,彈性比 OAuth 1.0 高很多。
  • 角色分工更清楚:把 Authorization Server 跟 Resource Server 的角色拆得更清楚,也更方便串接像 OpenID Connect 這類建立在 OAuth 之上的協定。

💡 其實不管是 OAuth 1.0 還是 OAuth 2.0,它們的本質都是 授權(Authorization) 協定,而不是 驗證(Authentication) 協定。

OAuth 2.0 雖然經常被拿來實作「登入」,但它本身並不是為了驗證使用者身分而設計的。

至於 OAuth 2.0 實際上有哪些授權流程(Grant Types)、每種流程適合什麼情境,以及要怎麼正確使用,後面會再完整拆解。


小結

OAuth 1.0 想解決的問題,是讓第三方應用程式在不取得使用者密碼的前提下,取得使用者授權並存取受保護資源。它透過三腳授權流程,讓 Client 先取得臨時憑證,等使用者同意後,再交換成可以實際呼叫 API 的 Access Token。

它最大的特色是「每個請求都要簽章」:Client 不只是帶著 Token 呼叫 API,還要用 Consumer Secret 和 Token Secret 算出 Signature,讓 Server 確認請求沒有被竄改,也確實來自持有正確金鑰的 Client。

以下整理出三個重點:

  1. OAuth 1.0 已經解決了「不要把密碼交給第三方 App」的問題:使用者是在服務本身完成授權,第三方 App 拿到的是授權後的憑證,而不是使用者密碼。
  2. 它的安全性很大一部分來自簽章機制:每次請求都要正確計算 Signature,這讓請求比較不容易被偽造,但也讓實作與除錯變得複雜。
  3. 它最後被 OAuth 2.0 取代:不是因為 OAuth 1.0 完全不能用,而是因為它太難實作、流程彈性不足,也不容易支援後來出現的 Mobile App、SPA、Server-to-Server 與 IoT 等場景。

下一篇會進入 OAuth 2.0。OAuth 2.0 不是 OAuth 1.0 的小幅升級,而是一次重新設計:它拿掉強制簽章,改用 Bearer Token 搭配 HTTPS,並用不同 Grant Type 支援更多應用場景。


參考資源


上一篇
Day 06|LDAP 與 Kerberos:企業目錄服務與票證驗證
下一篇
Day 08|OAuth 2.0:授權框架的基礎架構與角色
系列文
從登入到授權-現代軟體的身分架構指南9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言