OAuth 2.0 授權框架
之前在討論 API 身分驗證時,已有小提一下 OAuth 2.0 授權框架(以下簡稱 OAuth2)的概觀了。
授權與存取控制
在開始講細節之前,先簡單說明一下身分驗證(authentication)、授權(authorization)與存取控制(access control)的差異,有些人很容易把這三者搞混。
存取控制如 ACL(access control list)或 RBAC(role-based access control)。
身分驗證
透過身分驗證,可以讓系統知道目前的使用者是哪個實體。
如:輸入 root 帳號密碼成功,可以知道現在進來的使用者,是 Linux 裡所定義的超級使用者(super user)。
授權
在 OAuth2 的世界裡,授權指的是使用者,讓第三方應用程式取得使用者的資源。
如:使用者的大頭照放在 Facebook,而某個第三方軟體如 iT 邦幫忙,想取得使用者的大頭照,必須要經過使用者授權。注意:要或不要的決定權在於使用者。
存取控制
系統管理者,或被授權的使用者,才有權利更改存取控制的策略。目的是管理並控制使用者存取資源的權限。
如:留言板系統,前台使用者只能留言,後台使用者可以刪除留言。再一次與授權比較如下:
- 存取控制:管理者控制使用者可存取哪些資源
- 授權:使用者可控制第三方應用程式能存取哪些資源
OAuth 2.0 的授權流程
首先要了解 OAuth2 所定義的角色:
- resource owner - 資源擁有者,即「使用者」
- resource server - 資源伺服器,用來存放使用者受保護資源的伺服器
- client - 第三方應用程式,是對資源擁有者的資源有興趣的服務
- authorization server - 授權伺服器,專門用來處理授權的伺服器
而這四個角色之間的互動如下:
下圖源自 RFC 6749 1.2
@startuml |
以「iT 邦幫忙,想取得使用者在 Facebook 的大頭照」為例:
- iT 邦幫忙請求使用者的授權。可以直接發出授權請求,或是透過 Facebook 做為中介
- iT 邦幫忙收到同意授權的憑據,此憑據是由 OAuth2 裡所定義的四種流程的其中一種來傳送給 iT 邦幫忙
- iT 邦幫忙使用憑證向 Facebook 要求 access token
- Facebook 驗證 iT 邦幫忙的身分,並確認同意授權的憑據有效,即可發 access token
- iT 邦幫忙使用 access token 向 Facebook 請求資源
- Facebook 確認 access token 無誤,即可回傳資源給 iT 邦幫忙
從上面這個流程可以發現,除了第二步不明確之外,其他流程都很清楚:要求授權,使用者同意即可拿到 access token,接著就可以拿到想要拿的資源。
OAuth 2.0 Grant Type
OAuth2 是一個設計很靈活的框架,不但預定義了四種授權類型,同時也保留了彈性可以自定義類型,如 RFC 7521 - Assertion Framework for OAuth 2.0 Client Authentication and Authorization Grants 是利用 Assertion(如 SAML Assertion 或 JWT)來換取 access token 的框架。
預定義的授權類型如下:
- Authorization code grant
- Implicit grant
- Resource owner password credentials grant
- Client credentials grant
其中 client credentials grant 類似之前 API 身分驗證所提到的信任服務機制,屬於服務與服務之間的串接,而不經由使用者。
@startuml |
其他三種授權類型都會經由使用者,其中最簡單,同時也被定義為最後無路可走才能用的方法為 resource owner password credentials grant,簡單來說,它是使用者將帳號密碼直接提供給第三方應用程式,而第三方應用程式再拿來向授權伺服器要求 access token。
@startuml |
Resource owner password credentials grant 只能用在授權伺服器對第三方應用程式有足夠的信任(如,公司內部服務串接),不然像 Facebook 帳號密碼提供給第三方應用程式處理,其實是非常不安全的。
Implicit grant 可以用於如 SPA 或 App 等,沒有後端服務的場景。
@startuml |
從圖可以了解,access token 最終會存放在 UserAgent 裡,這其實不是很安全的方法,只要 UserAgent 有漏洞,token 就有可能外流。
一般最常見,也相較安全的方法還是使用 authorization code grant 較多。明天將會對此流程做比較詳細的說明。