從零開始SpringCloud Alibaba電商系統(九)——基於Spring Security OAuth2實現SSO(非JWT)

零、系列

歡迎來嫖從零開始SpringCloud Alibaba電商系列:

  1. 從零開始SpringCloud Alibaba電商系統(一)——Alibaba與Nacos服務註冊與發現
  2. 從零開始SpringCloud Alibaba電商系統(二)——Nacos配置中心
  3. 從零開始SpringCloud Alibaba電商系統(三)——Sentinel流量防衛兵介紹、流量控制demo
  4. 從零開始SpringCloud Alibaba電商系統(四)——Sentinel的fallback和blockHandler
  5. 從零開始SpringCloud Alibaba電商系統(五)——Feign Demo,Sentinel+Feign實現多節點間熔斷/服務降級
  6. 從零開始SpringCloud Alibaba電商系統(六)——Sentinel規則持久化到Nacos配置中心
  7. 從零開始SpringCloud Alibaba電商系統(七)——Spring Security實現登錄認證、權限控制
  8. 從零開始SpringCloud Alibaba電商系統(八)——用一個好看的Swagger接口文檔

一、概念

基於Cookie和Session的會話機制

介紹OAuth2之前,讓我們先來回顧一下早期的登錄認證流程。
遠古時期,互聯網上還只是一個共享的地方,沒有誰不能看什麼這樣的概念;隨着時代發展,互聯網引用豐富,基於商業和隱私,人們對登錄認證有了需求,但是大家都知道HTTP本身是無狀態的協議,是沒辦法讓HTTP來識別用戶身份的。

於是在上古時期,HTTP引入了Authorization請求頭,用戶可以將自己的用戶名密碼放入到這個請求頭中,服務端收到一條請求時先解析Authorization請求頭,確認用戶身份。

中古時期,人們覺得HTTP請求頭在自己內網用用還行,放在互聯網上太危險了,畢竟用戶名密碼就在HTTP的請求頭裏面放着,隨便誰攔截了都能看的清清楚楚,都能copy你的信息冒充你來請求資源。

於是大家都開始自己搞認證,而自己搞最常用的方式便是基於Form表單的自定義認證方式,畢竟Form表單中的數據屬於自定義請求數據,而Aithorization屬於HTTP的標準請求頭。Form表單認證,基本上就等同於基於Cookie和Session的會話機制

典型的會話機制如下圖所示,服務器端維護一個會session,客戶端持有這個session的id,這樣只要你登錄一次,服務器端就知道你是誰了。大致流程是這樣的:
在這裏插入圖片描述
越過千年的羈絆,再看現在,由於當下分佈式、微服務的常規化,大部分企業都已經不再是單體應用服務器,那麼Session的使用便成爲一個問題。

SSO就是解決這一類問題的方案的統稱,俗稱單點登錄,即對於用戶來說,登錄系統就是登錄了,我不需要在乎你裏面有幾個子系統,內部複雜度自己搞定。

JWT

衆多解決方案之中,有一個亮眼的存在——JWT(JSON Web Token)

JWT不是基於Session工作的,而是將用戶信息使用一種加密方式全都存放在cookies中,這樣的方式顯然能處理分佈式系統的登錄問題,因爲只要持有JWT令牌,你願意訪問哪個子系統就訪問哪個子系統,你願意何時訪問就何時訪問。

但是問題在於這個隨意,令牌就像央行發出去的鈔票,太難控制了,服務器系統不知道是誰拿着令牌,務器端不進行保存/管理,即jwt令牌一旦發放,其銷燬、續期、登出等功能將很難控制。

話無絕對,人總是聰明的,解決方法總是有的,有興趣的朋友可以多瞭解一下jwt,現在它還是很流行的:https://jwt.io/introduction/

OAuth2

我們今天的主角是OAuth2:OAuth2是一種可用於實現SSO單點登錄的一種協議。

OAuth 2.0關注客戶端開發者的簡易性。要麼通過組織在資源擁有者和HTTP服務商之間的被批准的交互動作代表用戶,要麼允許第三方應用代表用戶獲得訪問的權限。同時爲Web應用,桌面應用和手機,和起居室設備提供專門的認證流程。 ————— 百度百科

OAuth2協議的官方文檔:https://tools.ietf.org/html/rfc6749

綜(說)上(句)所(人)述(話),OAuth2的核心就是:服務器就負責提供服務,用戶端就負責消費服務,認證和授權的事情都交給認證服務器,資源服務器就只提供資源,簡要思想見下圖。

這個OAuth2怎麼好用了呢?讓我們來用Session作詳細描述(首先讓我們承認直接使用Session比使用JWT這樣方法出去的令牌好簡單方便,對用戶更友好)。

  1. 用戶需要訪問工單系統,需要登錄,於是發送用戶密碼到工單系統。
  2. 工單系統不直接鑑權,而是將用戶請求、自己的回調地址都轉發給認證中心。
  3. 認證中心知道用戶要登錄,於是給用戶一個登錄頁面,讓用戶輸用戶密碼。
  4. 認證中心拿到用戶密碼進行鑑權,認證通過,ok,我認證中心建立一個全局Session,代表這個用戶在我這個系統已經登陸了,然後,由於此時認證中心還持有工單系統的回調地址,所有可以直接發送給工單系統一個授權碼
  5. 工單系統拿到授權碼,再次通過授權碼向工單系統請求授權令牌
  6. 認證中心校驗授權碼,ok沒問題,給你工單系統一個令牌。
  7. 工單系統拿到令牌,就有權限訪問資源服務器上的相關資源了。同時工單系統與用戶建立了局部Session,兩者可以順暢交互。

在這裏插入圖片描述
大家會發現,感覺好像和JWT這種直接將令牌發給用戶的方式有些類似,確實類似,類似在令牌由認證中心授權給工單系統(俗稱client系統),而非直接給用戶。 client系統擁有資源訪問權限,且與用戶建立局部Session後,就可以實現一個用戶端的無Token訪問,即用戶不需要再持有Token令牌了,對於我用戶來說,還和單機時代一樣,持有個局部Session id就行。

工單系統解決了認證問題,那運維繫統呢?按理來說對於我用戶來說已經登錄了,點開運維繫統應該不用登陸了,這才符合SSO單點登錄原則嘛!

對於新的要訪問的子系統,OAuth2是這樣做的:

  1. 用戶對運維繫統發起請求。
  2. 運維繫統同樣將請求、自身回調地址轉發給認證中心。
  3. 認證中心發現該用戶的全局Session存在,不再鑑權,直接給運維繫統一個授權碼
  4. 運維繫統拿到授權碼,向認證中心請求授權令牌
  5. 認證中心校驗授權碼,校驗沒問題,返回授權令牌
  6. 運維繫統拿到授權令牌,可以訪問資源服務器了,同時與用戶建立局部Session

細心的同學可能發現了,運維繫統與工單系統不同的地方僅僅在於,運維繫統的鑑權直接由認證中心完成,沒有再讓用戶來一次登錄操作。除此之外,其他操作都一模一樣。

二、OAuth2認證服務器搭建

TODO 待續,很快補上。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章