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_code
、implicit
等
欄位設定有非常多,這裡提幾個來看看。
在註冊完 Client 加上有了這些資訊後,就有辦法跟透過此 OpenID Provider 做身分驗證。包括 Hydra、Google、AppleID、Line 都有辦法串接。
這裡也閒聊一下串接遇到的問題:
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_token
與 none
。顧名思義,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 Flow 和 Hybrid Flow 沒有講到,但實務上在 Web 上最常使用的是 Authorization Code Flow,相信已能滿足大部分情境需求。