iT邦幫忙

2022 iThome 鐵人賽

DAY 19
2
Software Development

30 天與九頭蛇先生做好朋友系列 第 19

由應用程式啟動登出流程

  • 分享至 

  • xImage
  •  

昨天有提到一個問題,但並沒有特別解釋相關的處理方法,是不同的撤銷情境,該怎麼實作。

Token 撤銷權限的情境主要有三個:

  1. 時間到自動撤銷
  2. 使用者請求撤銷
  3. 非使用者請求撤銷

使用 Access Token 時,在第二和第三個情境下,通常沒有什麼差別。主要是因為 Token 的狀態是存在授權伺服器上,屬於中央集權式,因此所有服務都無法自己確認 Token 的狀態,都必須要問授權伺服器才能知道 Token 是否還有效等狀態。但 ID Token 就不是這樣了,之前提到 ID Token 有簽章可以保護 Claim 的資訊不被亂改;同時 Claim 也有過期時間可以知道何時失效,所以應用程式只要有公鑰,就能自行驗證 ID Token 是否有效。

ID Token 非常方便,而且可以有效節省網路傳輸資源,但隨之帶來的問題就是撤銷 Token 的情境。

在第二個情境下沒有問題,使用者主動跟應用程式說這個 ID Token 不想使用了,想提早撤銷權限,這時應用程式只要確保 ID Token 有移除即可。問題在於第三個情境,當今天擁有 ID Token 的是攻擊者,伺服器包括應用程式或授權伺服器,都無法主動撤銷這個 Token--因為 ID Token 的狀態是存在 Token 上,而不像 Access Token 是存在授權伺服器上。

ID Token 代表的是登入的憑證,若要把 ID Token 的權限撤銷,代表的意義其實就是登出。今天先說明第二個情境的實作方法,也就是應用程式該如何登出。

了解登出的協定

OpenID Connect 對此有定義應用程式該如何啟動登出,也就是 OpenID Connect RP-Initiated Logout 1.0 這份協定。不過這份協定裡面還依賴了很多資訊,這部分之後再來說明,先來看 Hydra 官方文件是如何實作登出的。

Hydra 是定義一個叫 Logout Flow 的文件,時序圖如下:

Image.jpeg

  1. 首先先由應用程式轉導到登出端點 http://127.0.0.1:4444/oauth2/sessions/logout,可以用 GET(302)或是 POST(200 + Form)。可以使用的參數後面會說明。
  2. 接著到了一個新的 Logout Provider,這裡類似 Login Provider 與 Consent Provider,會有一個 logout_challenge 在控制整個登出流程。
  3. Logout Provider 的任務是:給使用者提示畫面,讓使用者知道要登出了;當然也可以默默的就處理完登出。
  4. Logout Provider 確認使用者要登出後,再回傳 Hydra 這個結果。
  5. Hydra 會執行登出,這時會更新該 Session 的狀態為已登出
  6. 完成後就回到應用程式的 Callback

登出端點跟流程比較有關係的欄位如下(詳細欄位說明可以參考協定):

欄位 必填 說明
id_token_hint RECOMMENDED 這裡要給當初登入的 ID Token,可以提示授權伺服器目前登入的身分等資訊。
client_id OPTIONAL 應用程式的唯一識別碼。
post_logout_redirect_uri OPTIONAL 登出完後要導回應用程式的哪個地方。
state OPTIONAL 與登入所使用的 state 欄位意義相同。

首先從這裡的資訊可以了解,就協定的定義來說,其實不傳參數也是能動的,只是轉導去哪,必須要由授權伺服器設定。而直接打開這頁的話,Hydra 會提示要設定 urls.post_logout_redirect 為預設轉導網址。

若想要使用 post_logout_redirect_uri 轉導回應用程式就必須額外註冊對應 URL,對 Hydra 來說,這是一開始註冊應用程式就要提供的。文件還有提到如果有提供這個欄位的話,建議也要給 id_token_hint。這個推測應該是為了確保不被 CSRF 攻擊,因為實際上,如果只有 post_logout_redirect_uri 欄位的話,那登出網址是可以散布的,但如果含有 id_token_hint 的話就沒辦法了。

而對於使用者來說,使用同個身分驗證中心,並進入不同的應用程式,是件很方便的事。相反地,對於授權伺服器來說,控制身分驗證的狀態就不是那麼容易,尤其是要清除登出狀態的時候。協定裡有提到當應用程式啟動登出之後,其他應用程式應該如何接受到這個訊息,並把使用者狀態一同清除,主要有下面三個協定:

  1. OpenID Connect Session Management 1.0
  2. OpenID Connect Front-Channel Logout 1.0
  3. OpenID Connect Back-Channel Logout 1.0

該使用哪個協定,由應用程式和授權伺服器約定好方法執行,因此也是註冊的時候設定即可。Hydra 這三個協定都有實作,筆者只有實作過第三種方法,因此後續會用這個協定來做說明。

今天只跟大家說明清除 ID Token 遇到的問題,以及該如何做登出,明天來實作 Logout Provider,以及協定裡面提到很多檢查項目,Hydra 是如何實作的。


上一篇
實作撤銷授權
下一篇
實作 Logout Provider
系列文
30 天與九頭蛇先生做好朋友23
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言