天天看點

從零搭建一個IdentityServer——會話管理與登出

  在上一篇文章中我們介紹了單頁應用是如何使用IdentityServer完成身份驗證的,并且在講到靜默登入以及會話監聽的時候都提到會話(Session)這一概念,會話指的是使用者與系統之間互動過程,反過來說就是使用者與系統之間互動的狀态就儲存在會話(Session)中,對于HTTP協定來說,由于它本身是無狀态的,是以為了能夠記錄使用者通路系統的狀态,一般使用Cookie來存放會話資訊。但是現在我們需要儲存的是與IdentityServer之間的會話,對于單頁應用來說它一般會存在跨域問題,那IdentityServer是如何處理跨域來完成會話管理的呢?同時IdentityServer4又提供了哪些與登入登出相關的特性?本文就從會話管理開始來一一介紹。

  本文内容有:

  • 會話管理
  • 前端登出
    • 授權伺服器(OP)登出關聯用戶端(RP)
    • 原了解析
    • 用戶端(RP)登出關聯授權伺服器(OP)
  • 後端登出
  • 小結
  • 關于會話Id(補充)

  首先會話本身有兩個主體,即伺服器和用戶端,服務端就是identityServer本身,它是一個asp.net core應用程式,那麼實際上它的會話機制就和普通的asp.net core應用程式是一緻的,通過cookie來儲存相應會話的id或資訊。

  下圖為登入IdentityServer後浏覽器端存儲的會話資訊和身份資訊:

從零搭建一個IdentityServer——會話管理與登出

  而對于用戶端來說,我們知道IdentityServer4實際上是OpenIDConnect(OIDC)協定的一個實作,而OIDC協定本身是沒有會話管理這一特性的,它的出現實際上是在一個補充協定中:https://openid.net/specs/openid-connect-session-1_0.html,該協定約定了用戶端如何對服務端的會話資訊進行管理,而協定的主要内容是以下幾個點:

  • 協定定義:如何持續監控終端使用者在OpenID Provider(OP,Identity Server)上提供的會話資訊,以便于終端使用者登出OpenID Provider(OP,IdentityServer)時能夠同時登出用戶端(Relying Party)。

  關于OP(IdentityServer)和RP(client)見下圖:

  

從零搭建一個IdentityServer——會話管理與登出

  簡單來說就是上一篇文章示範的“會話監控”内容,當使用者直接從IdentityServer直接登出時,用戶端本身能夠感覺到并作出相應動作(用戶端登出)。

  • iframe:一個HTML的标簽,它代表一個内嵌的HTML文檔,如果在HTML使用iframe那就是文檔中包含另一個文檔,iframe可以通過src屬性來設定包含文檔的url位址。當iframe設定的url與主文檔的url不同域時,可以使用iframe的postmessage方法實作跨域通信。

  關于iframe及postmessage可參考:https://blog.csdn.net/tang_yi_/article/details/79401280

  • RP iframe:位于用戶端(Relying Party, RP)中的一個iframe,這個iframe的作用是用于向OP iframe發送及接收資訊,發送的資訊是用于告知OP iframe進行會話檢查,接收的資訊是OP iframe完成會話檢查後的結果。

  下圖是oidc-client.js中用于建立RP iframe的代碼:

從零搭建一個IdentityServer——會話管理與登出

  下圖為使用RP iframe向OP iframe發送資訊的代碼:

從零搭建一個IdentityServer——會話管理與登出

  下圖為接收到OP iframe會話驗證結果消息後的處理代碼:

從零搭建一個IdentityServer——會話管理與登出
  • OP iframe:一個由OpenID Provider(OP,IdentityServer)提供的,位于用戶端(Relying Party, RP)中的一個iframe,它的作用是與IdentityServer同域,儲存于IdentityServer的會話資訊,并提供檢查接口(基于postmessage)的iframe。

  當使用者身份驗證成功後,oidc-client會根據配置資訊來通路擷取OP iframe:

從零搭建一個IdentityServer——會話管理與登出

  OP iframe請求:

從零搭建一個IdentityServer——會話管理與登出

  下圖為OP iframe中監聽RP iframe會話檢查消息,完成檢查并傳回消息結果的代碼:

從零搭建一個IdentityServer——會話管理與登出

  會話檢查是對使用者資料中包含的會話狀态(session_state)資訊進行核對,會話狀态(session_state)資訊分為兩個部分,它們用“.”分隔,前部分是用戶端id、用戶端域名、會話id加鹽計算出來的哈希值,後部分是哈希計算使用的鹽(salt)。

從零搭建一個IdentityServer——會話管理與登出

  下圖為會話檢查的具體邏輯,擷取目前的會話id并進行哈希計算後與使用者資訊中的哈希值進行核對,如果不一緻那麼認為會話發生變化。

從零搭建一個IdentityServer——會話管理與登出

  發生變化後oidc-client會自動發起授權請求來确認新會話的資訊,這個也就是上一篇文章登出後發起的請求傳回需要登入的原因:

從零搭建一個IdentityServer——會話管理與登出

  從以上内容看來oidc協定的會話管理主要是通過iframe完成的。

  下圖為單頁應用完成登入後發起靜默登入時候的頁面資訊:

從零搭建一個IdentityServer——會話管理與登出

  圖中存在兩個iframe,第一個是OP iframe包含了會話檢查相關内容,第二個是發起靜默登入時,建立的一個指向授權終結點的iframe,通過跨域完成登入,需要注意的是由于RP iframe是通過js代碼建立的,是以無法在頁面代碼中找到。

  到此為止我們了解到的僅僅是會話管理在單頁應用中實作的登入與登出功能,通過會話管理它可以将浏覽器與用戶端(RP)及授權伺服器(OP)之間的關系聯系起來,簡單來說就是當浏覽器與授權伺服器(OP)會話中斷時用戶端(RP)程式能夠知道(會話資訊改變),同時如果浏覽器與用戶端(RP)會話中斷時授權伺服器(OP)也能知道(先清除用戶端身份資訊,然後跳轉到授權伺服器登出界面)。

其次還有一個特點就是由于OIDC的會話管理協定是使用iframe來完成跨域會話檢查,雖然預設檢查頻率是2秒一次,但是它不需要向授權伺服器發送任何請求即可完成檢查,是以可以節省大量的網絡資源和伺服器資源。

  但最後看來這個會話管理協定隻适用于單頁應用來完成相關功能,但是對于web應用來說,使用單頁方式實作的僅僅是一部分,其它方式是如何處理用戶端(RP)與授權伺服器(OP)之間的登入聯系的呢?

  OIDC前端登出協定(OpenID Connect Front-Channel Logout),這個協定提供了一種登出的機制,該機制是通過浏覽器的前端技術來與被登出的用戶端(RP)/伺服器(OP)建立通信,不再需要iframe就可以實作相關登出功能,具體協定内容參見:https://openid.net/specs/openid-connect-frontchannel-1_0.html

  接下來我們就通過asp.net core應用程式來示範一下這個協定是如何完成前端登出的。

  1. API項目中添加一個登出頁面

  API項目實際上就是我們的用戶端(RP),目前的例子就是通過在該應用上添加一個登出頁面來完成授權伺服器登出後通知用戶端登出的功能。

  注:asp.net core api項目實際上是不包含頁面的,此處僅為了友善通過api項目中添加Razor頁面來完成示範。

  首先添加一個Razor頁面的布局:

從零搭建一個IdentityServer——會話管理與登出

  完成後獲得相關的目錄結構和必要檔案:

從零搭建一個IdentityServer——會話管理與登出

  添加一個登出頁面:

從零搭建一個IdentityServer——會話管理與登出

  後端代碼,代碼非常簡單,就是通過get方法通路該頁面時就直接進行登出操作:

從零搭建一個IdentityServer——會話管理與登出

  最後在Startup檔案中添加Razor Page的服務和路由:

從零搭建一個IdentityServer——會話管理與登出

   

從零搭建一個IdentityServer——會話管理與登出

  然後運作程式即可通路到代碼了:

從零搭建一個IdentityServer——會話管理與登出

  2. 授權伺服器中建立一個前端登出頁面,同時對Identity登出頁面改造:

  在本系列文章前面我們通過IdentityServer4內建asp.net core identity實作了使用者的登入登出功能,并且在使用中也暫時沒發現任何問題,可以滿足基礎的授權伺服器的登入和登出,但是如果要實作登出關聯,那麼就需要進行一些改造。

  主要改造有下面幾個步驟:

  1)添加一個前端登出頁面:

從零搭建一個IdentityServer——會話管理與登出

  2)對前端登出的Razor Page的後端Model中添加三個字段,并且用特性标明它們從Query中擷取:

從零搭建一個IdentityServer——會話管理與登出

  3)在前端登出的Razor Page的前端代碼中添加以下代碼:

從零搭建一個IdentityServer——會話管理與登出

  4)修改Identity登出頁面的後端Post請求處理方法:

從零搭建一個IdentityServer——會話管理與登出

  3. 修改用戶端資料,添加uri(用戶端新增的登出位址):

從零搭建一個IdentityServer——會話管理與登出

  4. 驗證登出關聯:

  首先通過IdentityServer完成身份驗證,并可通路受保護資源:

從零搭建一個IdentityServer——會話管理與登出

  然後開啟新的頁籤通路IdentityServer的登出頁面,此時因為用戶端程式是通過用戶端完成了授權伺服器的身份驗證,在浏覽器會話資訊儲存期間,它預設是登入狀态:

從零搭建一個IdentityServer——會話管理與登出

  最後我們點選登對外連結接,程式将攜帶相關參數跳轉到我們添加的前端登出頁面:

從零搭建一個IdentityServer——會話管理與登出

  現在我們再去重新整理受保護資源時得到以下結果,它跳轉到授權伺服器的登入頁面了,這意味着我們在授權伺服器(OP)登出的時候,用戶端(RP)同時也完成了登出:

從零搭建一個IdentityServer——會話管理與登出

原理簡析

  它們是如何完成關聯登出的呢?我們首先來分析一下相關主體有哪些:

  • 用戶端(RP)登出頁面:通路該頁面即可完成用戶端(RP)方面的登出,這個頁面用于授權伺服器登出關聯時通路。
  • 授權伺服器(OP)登出頁面:一個基于Asp.net core Identity的登出頁面,用于asp.net core應用程式(這裡特指授權伺服器)的登出。
  • 授權伺服器(OP)前端登出頁面:一個用于完成OIDC前端登出協定的登出頁面,負責用戶端登出頁面的調用及用戶端應用程式跳轉(該頁面功能有點類似于,我們在購買火車票付款時,首先跳轉到支付頁面,完成支付後通知系統已支付,并且又跳轉回訂單頁面的過程)。

   其次在整個過程中我們還使用了兩個比較重要的元件:

  • IdentityServer4的互動服務(Interaction Service):這個實際上就是identityServer4提供的一組接口,這些接口約定了使用者與IdentityServer4的互動方法,該接口可以通過依賴注入的方式進行使用。在本例中使用Interaction Service的目的是擷取目前登入使用者的登出上下文,以便完成後續登出工作(相關資訊存儲于Cookie中,類似基于Cookie身份驗證的身份資訊載體)。關于接口内容詳見文檔:https://identityserver4.readthedocs.io/en/latest/reference/interactionservice.html
  • 結束會話終結點(End Session Endpoint):就是字面意思,結束會話使用的終結點,在這裡的作用是通過結束會話終結點來終結會話并跳轉到用戶端(RP)的登出頁面完成用戶端(RP)登出。

  它的整個登出流程如下圖所示:

從零搭建一個IdentityServer——會話管理與登出

  簡單來說就是當使用者通路授權伺服器登出頁面并進行登出操作後,它進行授權服務應用登出後,跳轉到前端登入頁面,通過登出上下文資訊渲染了一個iframe元素,通過iframe完成結束會話終結點的通路和用戶端登出頁面的通路,最終呈現給使用者的就是前端登出頁面。

  下圖為登出操作後的網絡請求詳情:

從零搭建一個IdentityServer——會話管理與登出

  整個程式由登出頁面攜帶參數重定向到請求1(前端登入頁面),然後通過前端登入頁面的iframe發起請求2(結束會話終結點請求),最後再由結束會話終結點請求中的iframe完成用戶端登出請求3。

下圖為前端登入頁面在執行完成以上内容後的結果,從結果中我們可以看到兩個iframe分别對應了結束會話終結點請求和用戶端登出頁面請求:

從零搭建一個IdentityServer——會話管理與登出

  總的來說就是三個要點:

  1. 清除授權伺服器的身份資訊。

  2. 結束IdentityServer4的會話狀态。

  3. 清除用戶端的身份資訊。

  以上面所提到的三個要點來看如何實作用戶端(RP)與授權伺服器(OP)的登出關聯。

  首先我們在用戶端添(RP)加一個登出頁面:

從零搭建一個IdentityServer——會話管理與登出

  在頁面背景代碼中添加以下内容(主要是擷取id token然後拼接授權伺服器的結束會話終結點位址,另外就是登出):

從零搭建一個IdentityServer——會話管理與登出

  以下是頁面前端代碼,主要是通過iframe去通路結束會話終結點(注:使用iframe的目的是因為通路授權伺服器時能夠攜帶相關Cookie,以便進行身份驗證及登出操作):

從零搭建一個IdentityServer——會話管理與登出

  最後修改一下授權伺服器(OP)的登出頁面背景代碼,當接收到攜帶logoutId的Get請求時,對使用者進行登出操作(注:最後一句對User指派的代碼,是因為雖然應用程式執行了登出,但是User.Identity.IsAuthenticated仍然為true,這裡有找到一些資料可以進行參考:https://stackoverflow.com/questions/10663873/user-identity-isauthenticated-true-after-logout-asp-net-mvc

https://www.codeproject.com/tips/1115491/request-isauthenticated-is-always-true-after-call):

從零搭建一個IdentityServer——會話管理與登出

  接下來就開始驗證我們的關聯登出,首先確定受保護資源可通路:

從零搭建一個IdentityServer——會話管理與登出

  然後通路用戶端的登出頁面(https://localhost:51001/logoutwithop):

  通路登出頁面時,會觸發授權伺服器的登出頁面代碼,從代碼中我們可以看到相應的logoutId以及通過IdentityServer4互動服務獲得的登出上下文:

從零搭建一個IdentityServer——會話管理與登出

  通過斷點後,我們可以看到整個請求過程(請忽略相關404連結,是因為沒有添加靜态檔案進行中間件導緻的檔案無法擷取):

從零搭建一個IdentityServer——會話管理與登出

  iframe裡面的内容,可以看到授權伺服器已經成功登出:

從零搭建一個IdentityServer——會話管理與登出

  重新整理受保護資源會跳轉到授權伺服器進行身份驗證,這證明了用戶端本身已經完成登出:

從零搭建一個IdentityServer——會話管理與登出

  以上内容就是用戶端(RP)關聯授權伺服器(OP)的登出功能,總的來說還是三個要點:

  1. 清除用戶端的身份資訊。

  3. 清除授權伺服器的身份資訊。

  注:IdentityServer4中實際有兩個會話結束終結點,分别是EndSessionCallbackEndPoint和EndSessionEndPoint,前者用于OP關聯RP的登出,主要功能是渲染一個FrontChannelLogoutUrl的iframe來通路用戶端的前端登出頁面,後者是用于RP關聯OP時發起的結束會話請求,這個請求identityServer會儲存一個登出資訊,這個操作是EndSessionCallbackEndPoint不具備的,換句話說如果在OP關聯RP的場景下,用戶端(RP)的登出頁面(本例僅調用的HttpContext的Signout方法登出)還應該調用EndSessionEndPoint來給授權伺服器儲存登出資訊。本文為了簡化内容複雜性把兩個終結點都稱為了結束會話終結點。

  前面提到的無論是會話管理還是前端登出,它都有一個共同點就是基于浏覽器,因為浏覽器可以通過Cookie或者H5的存儲功能來儲存會話/狀态資訊,登出實際上就是把相應的資訊删除,這種情況下不管是用戶端(RP)還是授權伺服器(OP)它們本身都隻是去驗證身份資訊的有效性,如果身份資訊存在且有效那麼身份驗證通過,但是實際應用中可能會出現這麼一種情況,假設身份資訊過期時間足夠長,那麼隻要使用者不主動登出,那麼身份資訊将永久儲存、永久有效,服務端沒有“任何”一種方法能夠主動讓其失效,這是存在問題的,針對這種問題OIDC提出了後端登出這一概念。

  後端登出是什麼呢?它實際上是一種授權伺服器(OP)與用戶端(RP)之間直接通信的登出機制,簡單說來就是當通過授權伺服器(OP)登出時可以直接通知到用戶端(RP),不需要浏覽器的支援,說個具體場景就類似于微信可以同時在PC以及移動裝置上登入,但是移動裝置上可以直接控制PC登出,或者是當使用者修改密碼後,密碼修改前所有的會話都應被終止。

  後端登出雖然不再基于浏覽器的會話資訊,但是它畢竟需要明确知道相關登出的會話資訊,是以它本身比前端登出要複雜,需要授權伺服器(OP)以及用戶端(RP)都支援會話管理。對于授權伺服器來說可以通過通路https://localhost:5001/.well-known/openid-configuration來确定是否支援後端登出:

從零搭建一個IdentityServer——會話管理與登出

  而用戶端(RP)本身就得自己實作了,在實作用戶端的會話管理之前,還有一個概念需要了解一下,那就是登出令牌(Logout Token),它包含兩個比較重要的資訊,其一是使用者id(sub),其二是會話id(sid)具體參考文檔:https://openid.net/specs/openid-connect-backchannel-1_0.html#LogoutToken

擁有這兩個資訊,或者隻有對這兩個資訊進行管理,那麼在登出時我們才能知道到底是哪一個使用者的哪一次會話被結束了,那麼LogoutToken是怎麼來的呢?

  首先我們在用戶端(RP)添加一個用于接收後端請求的控制器(注:需要Post方法):

從零搭建一個IdentityServer——會話管理與登出

  然後将這個控制器的位址配置到IdentityServer的Client資料庫中:

從零搭建一個IdentityServer——會話管理與登出

  運作程式并執行上面介紹過的前端登出(OP關聯RP登出流程),就會觸發後端登出,在相應代碼設定的斷點會被觸發:

從零搭建一個IdentityServer——會話管理與登出

  在這個請求中我們發現Form表單中包含了logout_token:

從零搭建一個IdentityServer——會話管理與登出

  根據格式看來logout_token是一個jwt,以jwt方式解析該token獲得結果如下:

從零搭建一個IdentityServer——會話管理與登出

  其中包含了使用者id(sub)及此次會話id(sid),在此實驗基礎上,我們來實作一個簡單的用戶端會話管理。

  添加一個登出會話管理類型,該類型維護一個登出會話清單,它的功能是當接收到後端登出請求時将相應登出資訊存儲到清單中,使用者在身份驗證後來判斷使用者及目前會話是否存在于清單,如果存在清單中,那麼證明該使用者的目前會話已經被後端登出,應該被禁止:

從零搭建一個IdentityServer——會話管理與登出

  修改後端登出控制器代碼(此代碼僅用于測試,并未對任何異常情況進行處理,另外也未對token進行完整性驗證等,如果需要了解token驗證相關内容,可參考:https://github.com/IdentityServer/IdentityServer4/tree/main/samples/Clients/src/MvcHybridBackChannel):

從零搭建一個IdentityServer——會話管理與登出

  添加一個Cookie身份驗證事件處理器,當使用者通過身份驗證時去判斷sub及sid是否已經被登出:

從零搭建一個IdentityServer——會話管理與登出

  應用該事件處理器,先添加到容器,然後配置到Cookie身份驗證中:

從零搭建一個IdentityServer——會話管理與登出

  為了保證能夠驗證後端登出有效性,我們把前端登出代碼注釋後,運作程式(還是按照前端登出OP關聯RP流程,但前端登出代碼已經被注釋而失效了,是以如果登出成功,那就是後端登出的效果):

從零搭建一個IdentityServer——會話管理與登出

  當程式完成前端登出跳轉後,會自動觸發并進入登出流程:

從零搭建一個IdentityServer——會話管理與登出

  相應的使用者及會話已經被登出,是以需要拒絕并登出使用者:

從零搭建一個IdentityServer——會話管理與登出

  再次重新整理受保護資源,程式将跳轉到授權伺服器登入頁面,換句話說就是後端登出成功。

從零搭建一個IdentityServer——會話管理與登出

  以上就是後端登出内容(OP關聯RP進行後端登出),為什麼沒有RP關聯OP的後端登出?因為在非浏覽器環境下用戶端一般不會儲存與授權伺服器的身份驗證資訊(哪怕儲存了,那麼自己删除即可),是以自然就不存在RP登出需要關聯OP的場景。

  另外要注意的是後端登出原本是在非浏覽器環境下使用的,但上面的例子仍然是通過基于浏覽器的前端登出來完成的,其目的僅僅是為了友善示範,其次後端登出請求是由結束會話回調終結點(EndSessionCallback EndPoint)發起的(隻要用戶端資訊存在BackChannelLogoutUri資訊就會自動發起),那麼如果想主動發起該請求我們需要借助IBackChannelLogoutService來完成,該服務的SendLogoutNotificationsAsync方法可以通過使用者id、會話id以及用戶端id來發起相應用戶端的後端登出請求:

從零搭建一個IdentityServer——會話管理與登出

  關于如何擷取會話資訊來通過該服務發起登出會在後續文章中介紹。

  本文主要介紹了IdentityServer4的會話管理以及前後端登出功能。其中會話管理和前端登出都是基于浏覽器,通過浏覽器本身的Cookie及存儲功能來儲存相關身份、會話資料,同時借助Iframe來實作跨域請求、跨域會話檢查等等功能。

  對于前端登出來說它主要有授權伺服器(OP)與用戶端(RP)互相關聯兩種場景,無論使用者從哪一方進行登出操作都能夠将兩方的身份資訊删除。

  對于後端登出來說它要求授權伺服器(OP)與用戶端(RP)雙方都具備後端登出功能,IdentityServer4本身支援,而用戶端就需要自己實作了,本文中實作了一個簡單的登出會話管理功能,即當使用者觸發後端登出後,用戶端會記錄登出資訊,當使用者再次發起請求時,在身份驗證(驗證Cookie,此時Cookie仍然有效)後,來判斷該使用者是否已經後端登出,如果已經登出則主動拒絕通路。

  關于IdentityServer的會話管理,在文章前面我們就說過隻要登入到授權伺服器之後就會有一個名為“idsrv.session”的cookie,它代表使用者與授權伺服器此次會話的id,這裡有兩個問題,第一就是為什麼它的名稱是“idsrv.session”,是因為IdentityServer4中定義了一個預設的常量,如下圖所示:

從零搭建一個IdentityServer——會話管理與登出

  如果想要修改可以在IdentityServer的服務配置中,通過Authentication.CheckSessionCookieName來修改。

從零搭建一個IdentityServer——會話管理與登出

  第二個問題,這個cookie是如何出現的呢?為什麼登入了就有?登出了就被删除?是因為IdentityServer4實作了或者說包裝了asp.net core自有的身份驗證服務,實作了自己登入、登出邏輯,舉個登入例子,它先建立了會話Id然後又調用原有的登入邏輯:

從零搭建一個IdentityServer——會話管理與登出

  建立的會話Id是通過IdentityModel裡面的CryptoRandom類型生成的一個16位的唯一id,然後将這個id寫到cookie中:

從零搭建一個IdentityServer——會話管理與登出

  那麼這個會話id(sid)出現在什麼地方?又有什麼作用呢?從以前的文章中,我們可以看到Id_token、Access_token以及基于oidc身份驗證的使用者資訊、js單頁應用的用戶端都能看見會話id:

  Id_token:

 

從零搭建一個IdentityServer——會話管理與登出

  Access_token:

從零搭建一個IdentityServer——會話管理與登出

  asp.net core 應用程式使用者資訊:

從零搭建一個IdentityServer——會話管理與登出

  單頁應用中的使用者資料:

從零搭建一個IdentityServer——會話管理與登出

  雖然會話id存在的地方很多,但是它實際都是由首次登入的時候生成的,它們的使用過程如下:

  登入(生成會話id)→頒發ID Token/Access Token(包含會話id)→解析/驗證Token(獲得會話id)。解析驗證Token主要是對Id_Token進行驗證解析,從id_token中擷取相關資訊,這也是為什麼asp.net core應用及單頁應用中的使用者資料都包含會話id的原因。

  會話Id的作用也就是字面的意思,标記了相關内容是某次會話産生的。

  目前發現會話Id的應用有以下幾方面:

  1. 單頁應用的會話檢查:單頁應用的會話檢查主要是對session_state(由授權請求生成的包含sid加鹽哈希值和鹽的字元串)進行驗證,如果會話id發生變化(在同一會話下多次進行授權請求會話id不會變,但是鹽會發生變化,是以導緻session_state也不一緻,但由于會話檢查時是擷取實時的鹽,是以鹽的變化不會觸發會話變化事件),那麼就會觸發會話變化事件。

  2. 後端登出時也使用了會話id進行标記,以確定授權伺服器知道要登出哪一次會話,而用戶端被知道哪一個會話已經被登出。

  除此之外我們還可以在資料庫的persistedgrants(授權持久化)表中看到會話id的身影,标明了某一次Token的頒發情況:

從零搭建一個IdentityServer——會話管理與登出

  更多關于會話id的用法在後續内容中會持續關注。

PS.  這篇文章寫的時間跨度有點大,文章内容相對較多,并且有大量的檔案和代碼修改,但文中代碼均已圖檔形式展現,本系列文章完結後會上傳相關代碼檔案,如有問題可随時聯系作者。

參考:

https://stackoverflow.com/questions/10663873/user-identity-isauthenticated-true-after-logout-asp-net-mvc

https://www.codeproject.com/tips/1115491/request-isauthenticated-is-always-true-after-call

https://openid.net/specs/openid-connect-session-1_0.html

https://openid.net/developers/specs/

https://identityserver4.readthedocs.io/en/latest/reference/interactionservice.html

https://openid.net/specs/openid-connect-rpinitiated-1_0.html

https://github.com/IdentityServer/IdentityServer4/tree/main/samples/Clients/src/MvcHybridBackChannel

本文連結:https://www.cnblogs.com/selimsong/p/14630356.html

從零搭建一個IdentityServer——目錄(更新中...)

作者:7m魚

出處:http://www.cnblogs.com/selimsong/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

從零搭建一個IdentityServer——會話管理與登出

繼續閱讀