下面介紹其中幾個補充協定。

OpenID Connect Discovery

之前有提過 OpenID Connect 或 OAuth2 會提供很多 endpoint 以滿足各種流程運作需要。而做為一個 OpenID Provider,要在教學裡提供這些內容就會顯得有點瑣碎。

OpenID Connect Discovery 正是解決此問題的好方法,它定義 OpenID Provider 需要一個提供 URL 如:

http://example.com/.well-known/openid-configuration

即可回傳 OpenID Provider Metadata

token_endpoint REQUIRED / OPTIONAL OpenID Connect 讓 Client 取得 token 的端口。如果只支援 Implicit Flow 則不需要 userinfo_endpoint RECOMMENDED 透過 token 取得使用者個資的端口 jwks_uri REQUIRED 這裡會放 JWK Set 的內容,可以使用此內容來作為 JWK 處理,通常這裡放的是公鑰 registration_endpoint RECOMMENDED 動態註冊的端口 scopes_supported RECOMMENDED 支援哪些 Scope response_types_supported REQUIRED 指 response_type 有哪些可以用 response_modes_supported OPTIONAL 指 response_mode 有哪些可以用 grant_types_supported OPTIONAL 如 authorization_codeimplicit

欄位設定有非常多,這裡提幾個來看看。

在註冊完 Client 加上有了這些資訊後,就有辦法跟透過此 OpenID Provider 做身分驗證。包括 Hydra、GoogleAppleIDLine 都有辦法串接。

這裡也閒聊一下串接遇到的問題:

  • Hydra 與 Google 串接上都非常順利
  • Line 小麻煩一點,因為它 jwks_uri 看到的是 ES256,但簽出來的 JWT 是 HS256,後來查文件才知道 secret 是申請 Client 所給的 secret
  • AppleID 的 secret 需要另外做點手腳來產生,另外 Discovery 所回傳的並不是正規的 JSON 檔,所以需要 hack 資料。
  • 但不管怎麼說,裡面的資訊對於串接服務而言,是足夠使用的。

    OpenID Connect Dynamic Registration

    OpenID Connect Discovery 在定義 OpenID Provider 的 metadata,而 OpenID Connect Dynamic Registration 有部分則是在定義 Client 的 metadata。比方說相關的欄位如下:

    欄位設定有非常多,這裡提幾個來看看。

    從這裡可以了解,以 OpenID Provider 或 OAuth2 的角度來看,第三方應用程式在註冊的時候,應該要求哪些資訊作記錄。除此之外,像 GitHub Marketplace 也是眾多的 Client metadata 集合起來而成的。

    可以回頭去翻閱如 Google 或 Facebook 等授權伺服器的註冊 Client 表單比較看看,大家要求的資訊都相差不多。

    註冊完後的回應內容如下:

    註冊完成即可使用 Client Metadata 配合 OpenID Provider Metadata 來串接身分驗證了。

    最後補充一下,OAuth2 也有定義動態註冊可以參考:RFC 7591 - OAuth 2.0 Dynamic Client Registration Protocol,兩個協定都是互相參考,概念上大同小異,就不多討論了。

    OAuth 2.0 Multiple Response Types

    之前討論 OAuth2 時,有提到授權請求的 response_type 欄位要填 code,也能填 token(Implicit Grant)。而這個協定在定義如何摻在一起做 code token

    首先裡面有提到兩個新的 response type 為 id_tokennone。顧名思義,id_token 是回傳帶有 ID Token 參數;none 則是什麼都沒有。

    而上述的 type 除了 none 以外,其他三種 type 的組合技如下:

    code token code id_token id_token token code id_token token

    以最後一個 code id_token token 例子來說,是指回到 redirect uri 時,會把這三個參數一起帶回去。而組合的設計會衍生另一個問題是:順序要怎麼擺才對?類似地,scope 也有這種樣貌,但因為 OAuth2 一開始定義的時候,就是空白隔開的多個授權範圍,所以沒有順序的問題,而 response_type 是定義成字串,才會衍生順序的問題。

    筆者建議原則上以協定的順序為主,尤其是要自己實作 OpenID Provider 的時候,更要守規距。除非是實作 Client,且打算完全依賴 Discovery 的資訊(如 Google 的順序就跟協定不同)。

    Response Mode

    上面都是在討論回傳的內容有什麼,那該如何傳給 Client 呢?因此協定又有另外定義 Response Mode 作為回傳的方法,這裡是將 OAuth2 所定義的方法,再次重新定義成授權請求的新參數 response_mode

    query,參數編碼後,作為 redirect_uri 的 query 字串傳遞,通常用在 Authorization Code Grant fragment,參數編碼後,放在 redirect_uri 的 fragment 傳遞,通常用在 Implicit Grant

    response_mode 可以指定授權伺服器在回應的時候,要用什麼方法傳。(如果授權伺服器有支援的話)

    題外話:筆者之前串接過 AppleID,如果沒帶 response_mode 參數,則 AppleID 串接會失敗。

    OAuth 2.0 Form Post Response Mode

    OpenID Connect 除了定義 response_mode 還另外定義了新的方法為 Form POST:

    form_post,參數編碼後,放在 body 裡,然後用自動提交的 Form POST 傳給 Client 的 redirect_uri

    截至目前為止,OpenID Connect 的簡介算告一段落,雖然它還有定義 Implicit FlowHybrid Flow 沒有講到,但實務上在 Web 上最常使用的是 Authorization Code Flow,相信已能滿足大部分情境需求。