Spring Cloud Security OAuth2.0 認證授權系列(一) 基礎概念

架構技術專欄發表於2020-11-23

世界上最快的捷徑,就是腳踏實地,本文已收錄【架構技術專欄】關注這個喜歡分享的地方。

前序

最近想搞下基於Spring Cloud的認證授權平臺,總體想法是可以對服務間授權,想做一個基於Agent 的無侵入的方式。

因為新版本的Spring Cloud Security 、 OAuth2.0 貌似改了些東西,說上網隨便翻翻,但發現沒有針對Spring Security OAuth2.0認證授權系統性的文章。

遂結合一些資料和自己的一些梳理,來搞一個認證授權系列,就當是一個總結了。

其實前面我也搞了幾個關於認證授權的文章,但總感覺太零碎了,不成體系,沒搞過 Security 、OAuth2.0、JWT的人會一臉懵逼。

這次準備再從頭梳理下這方面的只是,逐步遞進。儘量不搞長篇大論,看的腦闊疼,爭取一篇一個點的推進。

話不多說,飯要一口口吃,基礎的東西其實也很重要,那就從頭來說吧。

基礎概念

1、認證的概念

在這個移動時代,我們每天都在各種APP間切換著,比如抖音、淘寶、微信等,比如我們拿抖音來舉例說明認證的一些基礎概念。

比如我們在使用抖音前都需要進行註冊吧,然後在輸入使用者名稱和密碼(或驗證碼)來登入賬號。

這裡登陸的過程就是 認證

那為什麼要認證?

認證,其實就是為了保護系統的資源,只有使用者身份合法才可以訪問資源。

認證 :使用者認證就是判斷一個使用者的身份是否合法的過程,使用者去訪問系統資源時系統要求驗證使用者的身份信

息,身份合法方可繼續訪問,不合法則拒絕訪問。

常見的使用者身份認證方式有:

  • 使用者名稱密碼登入
  • 二維碼登入
  • 手機簡訊登入
  • 指紋認證
  • 人臉識別

2、會話的概念

大家想想,如果我使用微信每點一個按鈕都要我進行一次認證,那我豈不是要瘋了。所以為了避免這種問題,在使用者認證完成後可將使用者資訊儲存在會話中。

會話其實就是系統保留了當前使用者登入狀態所提供的一種機制。

常見的會話方式:

  • 基於session
  • 基於token

基於session的認證方式:

1、使用者認證成功,在服務端將使用者資訊儲存在session中(目前很多為redis)

2、將sesssion_id返回給客戶端並存入 cookie 中

客戶端每次請求時帶上session_id,服務端就會根據其進行使用者合法性驗證。當使用者退出系統或session過期時,客戶端的session_id也就失效了。

基於token的認證方式:

1、使用者認證成功,在服務端會根據使用者資訊和某種加密手段生產一個token(如JWT)發給客戶端

2、客戶端將token存入 cookie 或 localStorage 中,在每次請求時帶上token,服務端就可以根據token進行使用者身份認證。服務端無需進行token儲存,因為使用者資訊都包含在token中。

注意:

  • session的認證方式由Servlet規範定製,服務端需儲存session,客戶端需要支援 cookie(如不支援cookie就需要特殊處理)

  • token的認證方式不需要服務端儲存token,並且不限制客戶端的儲存方式

  • 在現今的網際網路時代,系統多為前後端分離的架構設計,所以基於token的方式更好點

3、授權的概念

我們那微信來舉例,當使用者登陸成功後就可以使用發朋友圈、新增好友、發紅包等功能。

但此時如果我們沒有綁卡,是無法使用發紅包功能的,也就是說我們沒有發紅包的許可權。

只有繫結銀行卡的使用者才可以發紅包,也就是說此時的使用者擁有了發紅包的許可權。

這個根據使用者的許可權來控制使用者使用資源的過程就是授權 。

**為什麼要授權? **

認證是為了確認使用者的合法性,而授權是為了更細粒度的對資料進行劃分,授權是發生在認證完成後的,用來控制不同的使用者訪問不同的資源。

授權: 授權是使用者認證通過根據使用者的許可權來控制使用者訪問資源的過程,擁有資源的訪問許可權則正常訪問,沒有

許可權則拒絕訪問。

授權的資料模型

都知道寫程式碼有設計模式,經過總結,授權也有其資料模型

其實也就是哪些使用者,擁有哪些許可權,可以訪問哪些資源,如下圖:

關於上圖,我們可以抽象出幾個關鍵點:

who 對what 進行 how 操作

who : 使用者

what: 資源

how: 許可權

例如上面,使用者02 可以對商品資訊01 進行修改操作,其實這也是一種經典的授權方案,後面我們再來細說

然後通過上圖,可以抽象其中的關係,來幫助我們落地資料庫表設計,來一個經典的:

授權方案

如何實現授權的設計?其實業界有幾種常用方案:

  • ACL 訪問控制列表,表達和執行能力都較弱

  • RBAC 基於角色的許可權控制,表達能力有所欠缺,只能表達正向的訪問控制,反向控制較難

  • ABAC 基於屬性的許可權控制,能較好地表達反向訪問控制,但執行能力較差

  • PBAC 基於策略的許可權控制,結合了RBAC 和 ABAC 的最佳特性,它能實現更多應用場景複雜且靈活的管理控制需求

其中ABAC和PBAC在網際網路場景中很少使用,ACL是直接關係,RBAC是間接關係,所以我們來看下一般常用的RBAC

RBAC

RBAC許可權模型(Role-Based Access Control), 基於角色的許可權控制

在20世紀90年代期間,大量的專家學者和專門研究單位對RBAC的概念進行了深入研究,先後提出了許多型別的RBAC模型,其中以美國George Mason大學資訊保安技術實驗室(LIST)提出的RBAC96模型最具有系統性,得到普遍的公認。

RBAC認為許可權的過程可以抽象概括為:判斷【Who是否可以對What進行How的訪問操作】這個邏輯表示式的值是否為True的求解過程。

RBAC模型的資料庫建模

RBAC 將許可權問題轉換為Who、What、How的問題,其實根本就是使用者通過角色進行許可權關聯。

一個使用者可以擁有多個角色,一個角色又可以擁有多個許可權。這樣就構成了使用者 - 角色 - 許可權的授權模型。在模型中,使用者和角色之間,角色和許可權之間,一般是多對多關係,如圖。

這裡有個核心點,就是角色,可以理解為許可權的集合體,是一種載體。比如論壇的版主、超級管理員等,版主可以管理對帖子進行管理,這就是許可權。如果要給某個使用者授予這些許可權,只需要把角色賦予該使用者就好了,而不需要和許可權進行直接繫結。

進一步,增加許可權組設計

而在實際應用過程中會發現,當使用者量非常大的時候,如果我們要給每個使用者進行授權那真是累到手抽筋啊。所以,這時候就需要給使用者分組,分組後我們也可以直接給使用者組進行授權。這時使用者所擁有的許可權,就是使用者個人許可權和使用者組許可權之和。

我們來看看進化後的模型:

再進一步,增加頁面功能許可權設計

在我們實現場景中,對功能模組的操作、選單訪問、按鈕訪問、檔案上傳等都可屬於許可權的範疇。

在有些許可權設計中,會把功能操作作為一類,而把檔案、選單、頁面元素等作為另一類,這樣構成“使用者-角色-許可權-資源”的授權模型。

在做資料表建模時,可把功能操作和資源統一管理,也就是都直接與許可權表進行關聯,這樣可能更具便捷性和易擴充套件性

比如這裡我們有選單、檔案等功能,我們來看下許可權表更新後的設計:

這裡有幾個核心點說一下:

通過許可權表的許可權型別欄位,我們可以自有擴充套件自己的許可權。比如MENU代表選單許可權、FILE代表檔案許可權,我們在擴充套件時只需要建一張許可權XXX關聯表就可以了。

這裡許可權表、選單表、許可權選單關聯表是1對1的關係,所以如果新增一個選單就需要同時在三張表內插入記錄。在設計時也可以省去關聯表,直接叫許可權表和選單表進行關聯,只是需要在許可權表內增加一個記錄選單ID的欄位,方便後面進行區分。

好了,到目前為止,基於RBAC的許可權模型設計就完成了,來一個完整的設計圖

後序

本章節屬於針對於基礎概念做了些鋪墊,RBAC屬於重點內容,也屬於我們目前設計許可權也會經常用到的一種模式。

至於RBAC的表設計,其實萬變不離其宗,主要的還是搞清楚who、what、how。至於具體怎麼實現就看你的業務需求了,沒有完美的設計,只有不停的迭代。

後續計劃,大概說下

  • Spring Cloud Security 使用

  • 和OAuth2.0怎麼結合

  • 分散式系統的認證方案

  • 基於Spring CloudSecurity 實現分散式認證授權

相關文章