多是史上最全的權限系統設計

  權限系統設計
  
  前言
  
  權限管理是全部後臺系統的都會涉及的一個重要組成部分,主要目的是對不一樣的人訪問資源進行權限的控制,避免因權限控制缺失或操做不當引起的風險問題,如操做錯誤,隱私數據泄露等問題。
  
  目前在公司負責權限這塊,因此對權限這塊的設計比較熟悉,公司採用微服務架構,權限系統天然就獨立出來了,其餘業務系統包括商品中心,訂單中心,用戶中心,倉庫系統,小程序,多個APP等十幾個系統和終端
  
  1.權限模型
  
  迄今爲止最爲普及的權限設計模型是RBAC模型,基於角色的訪問控制(Role-Based Access Control)
  
  1.1 RBAC0模型
  
  RBAC0模型以下:
  
  這是權限最基礎也是最核心的模型,它包括用戶/角色/權限,其中用戶和角色是多對多的關係,角色和權限也是多對多的關係。
  
  用戶是發起操做的主體,按類型分可分爲2B和2C用戶,能夠是後臺管理系統的用戶,能夠是OA系統的內部員工,也能夠是面向C端的用戶,好比阿里雲的用戶。
  
  角色起到了橋樑的做用,鏈接了用戶和權限的關係,每一個角色能夠關聯多個權限,同時一個用戶關聯多個角色,那麼這個用戶就有了多個角色的多個權限。有人會問了爲何用戶不直接關聯權限呢?在用戶基數小的系統,好比20我的的小系統,管理員能夠直接把用戶和權限關聯,工做量並不大,選擇一個用戶勾選下須要的權限就完事了。可是在實際企業系統中,用戶基數比較大,其中不少人的權限都是同樣的,就是個普通訪問權限,若是管理員給100人甚至更多受權,工做量巨大。這就引入了"角色(Role)"概念,一個角色能夠與多個用戶關聯,管理員只須要把該角色賦予用戶,那麼用戶就有了該角色下的全部權限,這樣設計既提高了效率,也有很大的拓展性。
  
  權限是用戶能夠訪問的資源,包括頁面權限,操做權限,數據權限:
  
  頁面權限: 即用戶登陸系統能夠看到的頁面,由菜單來控制,菜單包括一級菜單和二級菜單,只要用戶有一級和二級菜單的權限,那麼用戶就能夠訪問頁面
  
  操做權限: 即頁面的功能按鈕,包括查看,新增,修改,刪除,審覈等,用戶點擊刪除按鈕時,後臺會校驗用戶角色下的全部權限是否包含該刪除權限,若是是,就能夠進行下一步操做,反之提示無權限。有的系統要求"可見便可操做",意思是若是頁面上可以看到操做按鈕,那麼用戶就能夠操做,要實現此需求,這裏就須要前端來配合,前端開發把用戶的權限信息緩存,在頁面判斷用戶是否包含此權限,若是有,就顯示該按鈕,若是沒有,就隱藏該按鈕。某種程度上提高了用戶體驗,可是在實際場景可自行選擇是否須要這樣作
  
  數據權限: 數據權限就是用戶在同一頁面看到的數據是不一樣的,好比財務部只能看到其部門下的用戶數據,採購部只看採購部的數據,在一些大型的公司,全國有不少城市和分公司,好比杭州用戶登陸系統只能看到杭州的數據,上海用戶只能看到上海的數據,解決方案通常是把數據和具體的組織架構關聯起來,舉個例子,再給用戶受權的時候,用戶選擇某個角色同時綁定組織如財務部或者合肥分公司,那麼該用戶就有了該角色下財務部或合肥分公司下的的數據權限。
  
  以上是RBAC的核心設計及模型分析,此模型也叫作RBAC0,而基於核心概念之上,RBAC還提供了擴展模式。包括RBAC1,RBAC2,RBAC3模型。下面介紹這三種類型
  
  1.2 RBAC1模型
  
  此模型引入了角色繼承(Hierarchical Role)概念,即角色具備上下級的關係,角色間的繼承關係可分爲通常繼承關係和受限繼承關係。通常繼承關係僅要求角色繼承關係是一個絕對偏序關係,容許角色間的多繼承。而受限繼承關係則進一步要求角色繼承關係是一個樹結構,實現角色間的單繼承。這種設計能夠給角色分組和分層,必定程度簡化了權限管理工做。
  
  1.3 RBAC2模型
  
  基於核心模型的基礎上,進行了角色的約束控制,RBAC2模型中添加了責任分離關係,其規定了權限被賦予角色時,或角色被賦予用戶時,以及當用戶在某一時刻激活一個角色時所應遵循的強制性規則。責任分離包括靜態責任分離和動態責任分離。主要包括如下約束:
  
  互斥角色: 同一用戶只能分配到一組互斥角色集合中至多一個角色,支持責任分離的原則。互斥角色是指各自權限互相制約的兩個角色。好比財務部有會計和審覈員兩個角色,他們是互斥角色,那麼用戶不能同時擁有這兩個角色,體現了職責分離原則
  
  基數約束: 一個角色被分配的用戶數量受限;一個用戶可擁有的角色數目受限;一樣一個角色對應的訪問權限數目也應受限,以控制高級權限在系統中的分配
  
  先決條件角色: 即用戶想得到某上級角色,必須先得到其下一級的角色
  
  1.4 RBAC3模型
  
  即最全面的權限管理,它是基於RBAC0,將RBAC1和RBAC2進行了整合
  
  import re
  
  import json
  
  class HtmlParser(object):
  
  def parser_url(self,page_url,response):
  
  pattern=re.compile(r'(http://movie.mtime.com/(\d+)/)')
  
  urls=pattern.findall(response)
  
  if urls != None:
  
  return list(set(urls))#Duplicate removal
  
  else:
  
  return None
  
  def parser_json(self,url,response):
  
  #parsing json. input page_www.kunlunyulegw.com rl as js url and response for parsing
  
  pattern=re.compile(r'=(.www.zzxcscl.com/*?);')
  
  result=pattern.findall(response)[0]
  
  if result != None:
  
  value=json.loads(result)
  
  isRelease=value.get('value').get(www.kunLunyuLegw.com'isRelease')
  
  if isRelease:
  
  isRelease=1
  
  return self.parser_json_release(value,url)
  
  else:
  
  isRelease=0
  
  return self.parser_json_notRelease(value,url)
  
  return None
  
  def parser_json_release(www.wanxinylegw.com self,value,url):
  
  isRelease=1
  
  movieTitle=value.get('value').get('movieTitle')
  
  RatingFinal=www.dfyLdL2019.com www.zzxcscl.com/ value.get('value').get('movieRating').get('RatingFinal')
  
  try:
  
  TotalBoxOffice=value.get('value').get('boxOffice').get('TotalBoxOffice')
  
  TotalBoxOfficeUnit=value.get(www.yfzc7.com'value').get('boxOffice').get('TotalBoxOfficeUnit')
  
  except:
  
  TotalBoxOffice="None"
  
  TotalBoxOfficeUnit="None"
  
  return isRelease,movieTitle,RatingFinal,TotalBoxOffice,TotalBoxOfficeUnit,url
  
  def parser_json_notRelease(self,value,url):
  
  isRelease=0
  
  movieTitle=value.get('value').get('movieTitle')
  
  try:
  
  RatingFinal=Ranking=value.get('value').get('hotValue').get('Ranking')
  
  except:
  
  RatingFinal=-1
  
  TotalBoxOffice='None'
  
  TotalBoxOfficeUnit='None'
  
  return isRelease,movieTitle,RatingFinal,TotalBoxOffice,TotalBoxOfficeUnit,url
  
  當平臺用戶基數增大,角色類型增多時,並且有一部分人具備相同的屬性,好比財務部的全部員工,若是直接給用戶分配角色,管理員的工做量就會很大,若是把相同屬性的用戶歸類到某用戶組,那麼管理員直接給用戶組分配角色,用戶組裏的每一個用戶便可擁有該角色,之後其餘用戶加入用戶組後,便可自動獲取用戶組的全部角色,退出用戶組,同時也撤銷了用戶組下的角色,無須管理員手動管理角色。
  
  根據用戶組是否有上下級關係,能夠分爲有上下級的用戶組和普通用戶組:
  
  具備上下級關係的用戶組: 最典型的例子就是部門和職位,可能多數人沒有把部門職位和用戶組關聯起來吧。固然用戶組是能夠拓展的,部門和職位經常使用於內部的管理系統,若是是面向C端的系統,好比淘寶網的商家,商家自身也有一套組織架構,好比採購部,銷售部,客服部,後勤部等,有些人擁有客服權限,有些人擁有上架權限等等,因此用戶組是能夠拓展的
  
  普通用戶組: 即沒有上下級關係,和組織架構,職位都沒有關係,也就是說能夠跨部門,跨職位,舉個例子,某電商後臺管理系統,有拼團活動管理角色,咱們能夠設置一個拼團用戶組,該組能夠包括研發部的後臺開發人員,運營部的運營人員,採購部的人員等等。
  
  每一個公司都會涉及到到組織和職位,下面就重點介紹這兩個。
  
  1.5.1 組織
  
  常見的組織架構以下圖:
  
  咱們能夠把組織與角色進行關聯,用戶加入組織後,就會自動得到該組織的所有角色,無須管理員手動授予,大大減小工做量,同時用戶在調崗時,只需調整組織,角色便可批量調整。組織的另一個做用是控制數據權限,把角色關聯到組織,那麼該角色只能看到該組織下的數據權限。
  
  1.5.2 職位
  
  假設財務部的職位以下圖:
  
  每一個組織部門下都會有多個職位,好比財務部有總監,會計,出納等職位,雖然都在同一部門,可是每一個職位的權限是不一樣的,職位高的擁有更多的權限。總監擁有全部權限,會計和出納擁有部分權限。特殊狀況下,一我的可能身兼多職。
  
  1.6 含有組織/職位/用戶組的模型
  
  根據以上場景,新的權限模型就能夠設計出來了,以下圖:
  
  根據系統的複雜度不一樣,其中的多對多關係和一對一關係可能會有變化,
  
  在單系統且用戶類型單一的狀況下,用戶和組織是一對一關係,組織和職位是一對多關係,用戶和職位是一對一關係,組織和角色是一對一關係,職位和角色是一對一關係,用戶和用戶組是多對對關係,用戶組和角色是一對一關係,固然這些關係也能夠根據具體業務進行調整。模型設計並非死的,若是小系統不須要用戶組,這塊是能夠去掉的。
  
  分佈式系統且用戶類型單一的狀況下,到這裏權限系統就會變得很複雜,這裏就要引入了一個"系統"概念,此時系統架構是個分佈式系統,權限系統獨立出來,負責全部的系統的權限控制,其餘業務系統好比商品中心,訂單中心,用戶中心,每一個系統都有本身的角色和權限,那麼權限系統就能夠配置其餘系統的角色和權限。
  
  分佈式系統且用戶類型多個的狀況下,好比淘寶網,它的用戶類型包括內部用戶,商家,普通用戶,內部用戶登陸多個後臺管理系統,商家登陸商家中心,這些作權限控制,若是你做爲架構師,該如何來設計呢?大神能夠在評論區留言交流哦!
  
  2.受權流程
  
  受權即給用戶授予角色,按流程可分爲手動受權和審批受權。權限中心可同時配置這兩種,可提升受權的靈活性。
  
  手動受權: 管理員登陸權限中心爲用戶受權,根據在哪一個頁面受權分爲兩種方式:給用戶添加角色,給角色添加用戶。給用戶添加角色就是在用戶管理頁面,點擊某個用戶去授予角色,能夠一次爲用戶添加多個角色;給角色添加用戶就是在角色管理頁面,點擊某個角色,選擇多個用戶,實現了給批量用戶授予角色的目的。
  
  審批受權: 即用戶申請某個職位角色,那麼用戶經過OA流程申請該角色,而後由上級審批,該用戶便可擁有該角色,不須要系統管理員手動授予。
  
  3.表結構
  
  有了上述的權限模型,設計表結構就不難了,下面是多系統下的表結構,簡單設計下,主要提供思路:
  
  4.權限框架
  
  Apache Shrio
  
  Spring Security
  
  在項目中能夠採用其中一種框架,它們的優缺點以及如何使用會在後面的文章中詳細介紹.
  
  5.結語
  
  權限系統能夠說是整個系統中最基礎,同時也能夠很複雜的,在實際項目中,會遇到多個系統,多個用戶類型,多個使用場景,這就須要具體問題具體分析,但最核心的RBAC模型是不變的,咱們能夠在其基礎上進行擴展來知足需求。
  
  最後,若是您以爲這篇文章對您有幫助,能夠點個贊,謝謝支持!前端

相關文章
相關標籤/搜索