.

  許可權系統設計
  
  前言
  
  許可權管理是所有後臺系統的都會涉及的一個重要組成部分,主要目的是對不同的人訪問資源進行許可權的控制,避免因許可權控制缺失或操作不當引發的風險問題,如操作錯誤,隱私資料洩露等問題。
  
  目前在公司負責許可權這塊,所以對許可權這塊的設計比較熟悉,公司採用微服務架構,許可權系統自然就獨立出來了,其他業務系統包括商品中心,訂單中心,使用者中心,倉庫系統,小程式,多個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模型是不變的,我們可以在其基礎上進行擴充套件來滿足需求。
  
  最後,如果您覺得這篇文章對您有幫助,可以