目錄

OAuth 2.0 之 Authorization Code Grant

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

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

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

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

時序圖如下:

sequenceDiagram
    Client->>ResourceOwner: Redirect to AuthorizationServer
    ResourceOwner->>AuthorizationServer: Resource Owner Authenticates
    AuthorizationServer->>ResourceOwner: Authorization Code
    ResourceOwner->>Client: Authorization Code
    Client-->>AuthorizationServer: Authenticates and request Access Token
    AuthorizationServer-->>Client: Access Token

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

欄位名稱必要參數說明
response_typeREQUIRED指的是回應類型為何,以此授權類型的話是 code
client_idREQUIREDclient 預先註冊好的唯一識別碼
redirect_uriOPTIONALclient 預先註冊好的轉導頁面
scopeOPTIONAL授權範圍
stateRECOMMENDED亂數,可用來確保授權請求與授權回應為同一使用者

而這些參數使用 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_typeREQUIRED協定規定為 authorization_code
codeREQUIRED授權成功回應的 code
redirect_uriREQUIRED必須與授權請求 redirect_uri 相同

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

欄位名稱必要參數說明
access_tokenREQUIRED授權服務發行的 token
token_typeREQUIRED說明 access token 是何種型式
expires_inRECOMMENDEDToken 多久後會過期
refresh_tokenOPTIONAL可用來重換新的 token
scopeOPTIONAL最終接受的授權範圍

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

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

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

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

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