OAuth 2.0 之 Authorization Code Grant

Authorization Code Grant 是相較其他三種授權類型而言,最複雜的一種。但就讓使用者授護的目的而言,這個授權類型相較設計的比較合理也安全。

Client credentials grant 設計上並沒有經過使用者授權,因此它雖然安全,但就目的而言不完全合理。

註冊 Client

之前討論身分驗證可以怎麼做的時候曾提過,在做身分驗證前要先註冊實體。同樣地,client 在開始要求授權之前,也得先跟授權伺服器註冊 client 的相關資訊。

註冊資訊 說明
client identifier client 的唯一識別碼
client authentication client 驗證的方法,如密碼或是 JWT
client password client 的密碼驗證方法,若授權伺服器有發密碼的話,則必須提供 HTTP basic authentication scheme
redirection endpoint 規範提到 public client 才需要,但實務上還是都會在註冊提供,以確保安全

授權流程

時序圖如下:

@startuml
ResourceOwner <- Client: Redirect to AuthorizationServer
ResourceOwner -> AuthorizationServer: Resource Owner Authenticates
ResourceOwner <- AuthorizationServer: Authorization Code
ResourceOwner -> Client: Authorization Code
Client --> AuthorizationServer: Authenticates and request Access Token
Client <-- AuthorizationServer: Access Token
@enduml

首先會由 client 透過 User Agent 發出授權請求(authorization request)到授權伺服器的授權端口(authorization endpoint),這個請求會帶有下列資訊:

欄位名稱 必要參數 說明
response_type REQUIRED 指的是回應類型為何,以此授權類型的話是 code
client_id REQUIRED client 預先註冊好的唯一識別碼
redirect_uri OPTIONAL client 預先註冊好的轉導頁面
scope OPTIONAL 授權範圍
state RECOMMENDED 亂數,可用來確保授權請求與授權回應為同一使用者

而這些參數使用 application/x-www-form-urlencoded 編碼後,把它作為 HTTP query 放到授權端口的後面,並產生 URI。接著讓 Client 使用 302 redirect 到此 URI。

接著這個端口該回應什麼,或是實際上要如何要求使用者授權,協定就沒有特別定義了。協定關心的是接下來的事:如何回傳授權結果給 client。

授權請求的 response_type 是使用 code,因此成功的話就會把帶有 code 資訊的請求,透過 User Agent 傳送給 redirection endpoint。另外如果授權請求有帶 state 的話,這裡會一併回傳給 client 做確認。

類似地,implicit grant 授權請求的 response_type 是使用 token,回傳給 client 的時候則帶有 access_token 資訊

Client 拿到 code 之後,它還不能拿來作為通行證使用,還需要再帶著 code 對授權伺服器提供的 token endpoint 發送 POST 請求。除此之外,還需要額外提供身分驗證資訊--指註冊的所約定好的驗證方法,如最常見的 id / secret 透過 http basic authentication 驗證。

欄位名稱 必要參數 說明
grant_type REQUIRED 協定規定為 authorization_code
code REQUIRED 授權成功回應的 code
redirect_uri REQUIRED 必須與授權請求 redirect_uri 相同

最後成功即可拿到 access token 資訊,以及 metadata。

欄位名稱 必要參數 說明
access_token REQUIRED 授權服務發行的 token
token_type REQUIRED 說明 access token 是何種型式
expires_in RECOMMENDED Token 多久後會過期
refresh_token OPTIONAL 可用來重換新的 token
scope OPTIONAL 最終接受的授權範圍

授權失敗的格式 RFC 裡面已有詳細說明,這裡就不多提

安全注意事項

在整個授權流程中,最需要保護的標的就是 token,包括 access token 與 refresh token。

從流程來看,Authorization Code Grant 相較安全的主因是:token 的傳輸都是在後端,對使用者而言是無感或不存在的。也因此攻擊者無法藉由使用者操作不當進而取得 token 與權限。

同時,code 也要盡可能避免被偷。因此一個簡單的方法是,註冊時同時綁定 redirect_uri 的白名單,這樣在授權請求可以進一步阻擋不合法的請求。而使用亂數的 state 並在 redirection endpoint 做確認,也能有效增加安全性。

小結

今天簡單說明了 Authorization Code Grant 的流程。接下來在看 OpenID Connect 時,將會用到今天所介紹的內容。

參考資料