[認證 & 授權] 5. OIDC(OpenId Connect)身份認證(擴展部分)


在上一篇[認證授權] 4.OIDC(OpenId Connect)身份認證(核心部分)中解釋了OIDC的核心部分的功能,即OIDC如何提供id token來用於認證。由於OIDC是一個協議族,如果只是簡單的只關注其核心部分其實是不足以搭建一個完整的OIDC服務的。本篇則解釋下OIDC中比較常用的幾個相關擴展協議,可以說是搭建OIDC服務必備的幾個擴展協議(在上一篇中有提到這幾個協議規范):

  1. Discovery:可選。發現服務,使客戶端可以動態的獲取OIDC服務相關的元數據描述信息(比如支持那些規范,接口地址是什么等等)。
  2. OAuth 2.0 Multiple Response Types :可選。針對OAuth2的擴展,提供幾個新的response_type。
  3. OAuth 2.0 Form Post Response Mode:可選。針對OAuth2的擴展,OAuth2回傳信息給客戶端是通過URL的querystring和fragment這兩種方式,這個擴展標准提供了一基於form表單的形式把數據post給客戶端的機制。
  4. 會話管理:Session Management :可選。Session管理,用於規范OIDC服務如何管理Session信息;Front-Channel Logout:可選。基於前端的注銷機制。

1 OIDC Discovery 規范

顧名思義,Discovery定義了一個服務發現的規范,它定義了一個api( /.well-known/openid-configuration ),這個api返回一個json數據結構,其中包含了一些OIDC中提供的服務以及其支持情況的描述信息,這樣可以使得oidc服務的RP可以不再硬編碼OIDC服務接口信息。這個api返回的示例信息如下(這里面只是一部分,更完整的信息在官方的規范中有詳細的描述和解釋說明:http://openid.net/specs/openid-connect-discovery-1_0.html):

相信大家都看得懂的,它包含有授權的url,獲取token的url,注銷token的url,以及其對OIDC的擴展功能支持的情況等等信息,這里就不再詳細解釋每一項了。

2 OAuth2 擴展:Multiple Response Types

在本系列的第一篇博客[認證授權] 1.OAuth2授權中解釋OAuth2的授權請求的時候,其請求參數中有一個 response_type 的參數,其允許的值有 code 和 token 兩個,在這兩個的基礎上,OIDC增加了一個新值 id_token (詳細信息定義在http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html):

  1. code:oauth2定義的。用於獲取authorization_code。
  2. token:oauth2定義的。用戶獲取access_token。
  3. id_token:OIDC定義的。用戶獲取id_token。

至此OIDC是支持三種類型的response_type的,不但如此,OIDC還允許了可以組合這三種類型,即在一個response_type中包含多個值(空格分隔)。比如當參數是這樣的時候 response_type=id_token token ,OIDC服務就會把access_token和id_token一並給到調用方。OIDC對這些類型的支持情況體現在上面提到的Discovery服務中返回的response_types_supported字段中:

3 OAuth2 擴展:Form Post Response Mode

在oauth2的授權碼流程中,當response_type設置為code的時候,oauth2的授權服務會把authorization_code通過url的query部分傳遞給調用方,比如這樣“https://client.lnh.dev/oauth2-callback?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz”。

在oauth2的隱式授權流程中,當response_type設置為token的時候,oauth2的授權服務會直接把access_token通過url的fragment部分傳遞給調用方,比如這樣“http://client.lnh.dev/oauth2-callback#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&expires_in=3600”;

在oauth2中,上面的兩種情況是其默認行為,並沒有通過參數來顯示的控制。OIDC在保持oauth2的默認行為的基礎上,增加了一個名為response_mode的參數,並且增加了一種通過form表單傳遞信息的方式,即form_post(詳細信息定義在http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html)。OIDC服務對這個擴展的支持情況體現在上面提到的Discovery服務中返回的response_modes_supported字段中:

當reponse_mode設置為form_post的時候,OIDC則會返回如下的信息:

  <html>
   <head><title>Submit This Form</title></head>
   <body onload="javascript:document.forms[0].submit()">
    <form method="post" action="https://client.lnh.dev/oidc-callback">
      <input type="hidden" name="state"
       value="DcP7csa3hMlvybERqcieLHrRzKBra"/>
      <input type="hidden" name="id_token"
       value="eyJhbGciOiJSUzI1NiIsImtpZCI6IjEifQ.eyJzdWIiOiJqb2huIiw
         iYXVkIjoiZmZzMiIsImp0aSI6ImhwQUI3RDBNbEo0c2YzVFR2cllxUkIiLC
         Jpc3MiOiJodHRwczpcL1wvbG9jYWxob3N0OjkwMzEiLCJpYXQiOjEzNjM5M
         DMxMTMsImV4cCI6MTM2MzkwMzcxMywibm9uY2UiOiIyVDFBZ2FlUlRHVE1B
         SnllRE1OOUlKYmdpVUciLCJhY3IiOiJ1cm46b2FzaXM6bmFtZXM6dGM6U0F
         NTDoyLjA6YWM6Y2xhc3NlczpQYXNzd29yZCIsImF1dGhfdGltZSI6MTM2Mz
         kwMDg5NH0.c9emvFayy-YJnO0kxUNQqeAoYu7sjlyulRSNrru1ySZs2qwqq
         wwq-Qk7LFd3iGYeUWrfjZkmyXeKKs_OtZ2tI2QQqJpcfrpAuiNuEHII-_fk
         IufbGNT_rfHUcY3tGGKxcvZO9uvgKgX9Vs1v04UaCOUfxRjSVlumE6fWGcq
         XVEKhtPadj1elk3r4zkoNt9vjUQt9NGdm1OvaZ2ONprCErBbXf1eJb4NW_h
         nrQ5IKXuNsQ1g9ccT5DMtZSwgDFwsHMDWMPFGax5Lw6ogjwJ4AQDrhzNCFc
         0uVAwBBb772-86HpAkGWAKOK-wTC6ErRTcESRdNRe0iKb47XRXaoz5acA"/>
    </form>
   </body>
  </html>

這是一個會在html加載完畢后,通過一個自動提交的form表單,把id_token,access_token,authorization_code或者其他的相關數據POST到調用方指定的回調地址上。

4 OIDC 會話管理

綜合上篇提到的idtoken和前面的discovery服務以及針對oauth2的擴展,則可以讓OIDC服務的RP完成用戶認證的過程。那么如何主動的撤銷這個認證呢(也就是我們常說的退出登錄)?總結來說就是其認證的會話管理,OIDC單獨定義了3個獨立的規范來完成這件事情:

  1. Session Management :可選。Session管理,用於規范OIDC服務如何管理Session信息。
  2. Front-Channel Logout:可選。基於前端的注銷機制。
  3. Back-Channel Logout:可選。基於后端的注銷機制。

其中Session Management是OIDC服務自身管理會話的機制;Back-Channel Logout則是定義在純后端服務之間的一種注銷機制,應用場景不多,這里也不詳細解釋了。這里重點關注一下Front-Channel Logout這個規范(http://openid.net/specs/openid-connect-frontchannel-1_0.html),它的使用最為廣泛,其工作的具體的流程如下(結合Session Management規范)

 

在上圖中的2和3屬於session management這個規范的一部。其中第2步中,odic的退出登錄的地址是通過Discovery服務中返回的end_session_endpoint字段提供的RP的。其中還有一個check_session_iframe字段則是供純前端的js應用來檢查oidc的登錄狀態用的。

4567這四步則是屬於front-channel logout規范的一部分,OIDC服務的支持情況在Discovery服務中也有對應的字段描述:

4567這一部分中重點有兩個信息:

  1. RP退出登錄的URL地址(這個在RP注冊的時候會提供給OIDC服務);
  2. URL中的sessionid這個參數,這個參數一般是會包含在idtoken中給到OIDC客戶端,或者在認證完成的時候以一個獨立的sessionid的參數給到OIDC客戶端,通常來講都是會直接把它包含在IDToken中以防止被篡改。

5 總結

本篇博客介紹了OIDC的發現服務,OAuth2的兩個擴展規范,以及OIDC管理會話的機制。至此則可以構成一個完整的認證和退出的流程。其中有一點需要特別注意,這個流程中用到的token是OIDC定義的IDTokenIDTokenIDToken(重要要的事情說三遍),而不是OAuth2中定義的Access Token,千萬不要混淆這兩者,它們是有着本質的區別的(這一點在[認證授權] 3.基於OAuth2的認證(譯)[認證授權] 4.OIDC(OpenId Connect)身份認證授權(核心部分)中都有解釋)。

6 Example

筆者基於IdentityServer3和IdentitySever4(兩者都是基於OIDC的一個.NET版本的開源實現)寫的一個集成SSO,API訪問授權控制,GIthub,QQ登錄(作為IDP)的demo:https://github.com/linianhui/oidc.example

參考

oidc : http://openid.net/connect/

oidc - discovery :http://openid.net/specs/openid-connect-discovery-1_0.html

oauth2 - multiple-response-types :http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html

oauth2 - form-post-response-mode :http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html

oidc - session-menagement :http://openid.net/specs/openid-connect-session-1_0.html

oidc - front-channel-logout :http://openid.net/specs/openid-connect-frontchannel-1_0.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM