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

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

前序

最近想搞下基於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 實現分佈式認證授權