1. 程式人生 > >面試題:如何設計一個許可權系統?

面試題:如何設計一個許可權系統?

前言

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

1.5 使用者組

當平臺使用者基數增大,角色型別增多時,而且有一部分人具有相同的屬性,比如財務部的所有員工,如果直接給使用者分配角色,管理員的工作量就會很大,如果把相同屬性的使用者歸類到某使用者組,那麼管理員直接給使用者組分配角色,使用者組裡的每個使用者即可擁有該角色,以後其他使用者加入使用者組後,即可自動獲取使用者組的所有角色,退出使用者組,同時也撤銷了使用者組下的角色,無須管理員手動管理角色。
根據使用者組是否有上下級關係,可以分為有上下級的使用者組和普通使用者組:

  • 具有上下級關係的使用者組: 最典型的例子就是部門和職位,可能多數人沒有把部門職位和使用者組關聯起來吧。當然使用者組是可以拓展的,部門和職位常用於內部的管理系統,如果是面向C端的系統,比如淘寶網的商家,商家自身也有一套組織架構,比如採購部,銷售部,客服部,後勤部等,有些人擁有客服許可權,有些人擁有上架許可權等等,所以使用者組是可以拓展的
  • 普通使用者組: 即沒有上下級關係,和組織架構,職位都沒有關係,也就是說可以跨部門,跨職位,舉個例子,某電商後臺管理系統,有拼團活動管理角色,我們可以設定一個拼團使用者組,該組可以包括研發部的後臺開發人員,運營部的運營人員,採購部的人員等等。

每個公司都會涉及到到組織和職位,下面就重點介紹這兩個。

1.5.1 組織架構

常見的組織架構如下圖:

我們可以把組織與角色進行關聯,使用者加入組織後,就會自動獲得該組織的全部角色,無須管理員手動授予,大大減少工作量,同時使用者在調崗時,只需調整組織,角色即可批量調整。組織的另外一個作用是控制資料許可權,把角色關聯到組織,那麼該角色只能看到該組織下的資料許可權。

1.5.2 職位

假設財務部的職位如下圖:

每個組織部門下都會有多個職位,比如財務部有總監,會計,出納等職位,雖然都在同一部門,但是每個職位的許可權是不同的,職位高的擁有更多的許可權。總監擁有所有許可權,會計和出納擁有部分許可權。特殊情況下,一個人可能身兼多職。

1.6 含有組織/職位/使用者組的模型

根據以上場景,新的許可權模型就可以設計出來了,如下圖:

根據系統的複雜度不同,其中的多對多關係和一對一關係可能會有變化,

  • 在單系統且使用者型別單一的情況下,使用者和組織是一對一關係,組織和職位是一對多關係,使用者和職位是一對一關係,組織和角色是一對一關係,職位和角色是一對一關係,使用者和使用者組是多對對關係,使用者組和角色是一對一關係,當然這些關係也可以根據具體業務進行調整。模型設計並不是死的,如果小系統不需要使用者組,這塊是可以去掉的。
  • 分散式系統且使用者型別單一的情況下,到這裡許可權系統就會變得很複雜,這裡就要引入了一個"系統"概念,此時系統架構是個分散式系統,許可權系統獨立出來,負責所有的系統的許可權控制,其他業務系統比如商品中心,訂單中心,使用者中心,每個系統都有自己的角色和許可權,那麼許可權系統就可以配置其他系統的角色和許可權。
  • 分散式系統且使用者型別多個的情況下,比如淘寶網,它的使用者型別包括內部使用者,商家,普通使用者,內部使用者登入多個後臺管理系統,商家登入商家中心,這些做許可權控制,如果你作為架構師,該如何來設計呢?大神可以在評論區留言交流哦!

2.授權流程

授權即給使用者授予角色,按流程可分為手動授權和審批授權。許可權中心可同時配置這兩種,可提高授權的靈活性。

  • 手動授權: 管理員登入許可權中心為使用者授權,根據在哪個頁面授權分為兩種方式:給使用者新增角色,給角色新增使用者。給使用者新增角色就是在使用者管理頁面,點選某個使用者去授予角色,可以一次為使用者新增多個角色;給角色新增使用者就是在角色管理頁面,點選某個角色,選擇多個使用者,實現了給批量使用者授予角色的目的。
  • 審批授權: 即使用者申請某個職位角色,那麼使用者通過OA流程申請該角色,然後由上級審批,該使用者即可擁有該角色,不需要系統管理員手動授予。

3.表結構

有了上述的許可權模型,設計表結構就不難了,下面是多系統下的表結構,簡單設計下,主要提供思路:

4.許可權框架

  • Apache Shrio
  • Spring Security

在專案中可以採用其中一種框架,它們的優缺點以及如何使用會在後面的文章中詳細介紹.

5.結語

許可權系統可以說是整個系統中最基礎,同時也可以很複雜的,在實際專案中,會遇到多個系統,多個使用者型別,多個使用場景,這就需要具體問題具體分析,但最核心的RBAC模型是不變的,我們可以在其基礎上進行擴充套件來滿足需求。
最後,如果您覺得這篇文章對您有幫助,可以點個贊,謝謝支援!

 





關注微信公眾號【程式設計師的夢想】,專注於Java,SpringBoot,SpringCloud,微服務,Docker以及前後端分離等全棧技術。

相關推薦

java算法試題設計一個快速排序。雙路快速排序,簡單易於理解。

面試題 != ava 思路 add bubuko 比較器 繼續 array package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.Com

試題如何設計一個許可權系統

前言 許可權管理是所有後臺系統的都會涉及的一個重要組成部分,主要目的是對不同的人訪問資源進行許可權的控制,避免因許可權控制缺失或操作不當引發的風險問題,如操作錯誤,隱私資料洩露等問題。 目前在公司負責許可權這塊,所以對許可權這塊的設計比較熟悉,公司採用微服務架構,許可權系統自然就獨立出來了,其他業務系統包括

linux試題刪除一個目錄下的所有文件,但保留一個指定文件

spa -a ash exclude 事先 file roo 老師 保留 面試題:刪除一個目錄下的所有文件,但保留一個指定文件 解答: 假設這個目錄是/xx/,裏面有file1,file2,file3..file10 十個文件 [root@oldboy xx]# to

試題判斷一個物件是不是陣列型別

<script> //判斷一個物件是不是陣列型別 typeof不能檢視所有型別 var obj1={x:1,y:2}, obj2=[1,2,3], obj3=new Date(); //1.判斷爹(原型物件)

試題編寫一個函式來查詢字串陣列中的最長公共字首。 如果不存在公共字首,返回空字串 ""。(c++實現)

例項說明 示例 1: 輸入: ["flower","flow","flight"] 輸出: "fl" 示例 2: 輸入: ["dog","racecar","car"] 輸出: "" 解釋: 輸入不存在公共字首。 說明: 所有輸入只包含小寫字母 a-z&

程式設計試題編寫一個會造成資料庫死鎖的應用

相信對於"開發一個會產生死鎖的Java應用”這類需求,大家都能順利完成。但是如果題目要求得更具體一些,要求這個死鎖發生在資料庫層面,應該怎樣完成呢? 下面我提供一種答案,採用SAP的程式語言ABAP(Advanced Business Application Programming)實現。 我們從ABAP幫

C#試題輸入一個長度100的數字字串,判斷是否能被7整除

輸入一個長度為100的數字字串,首字元不能是0,判斷是否能被7整除。 思路:把字串中各個位數字拿出來與7取餘,如果最後為0,表示可以整除,不為0表示不能整除。 例如:504:5%=5,50%7=1,14%7=0等於0。那麼504能被7整除。             21

11. 微軟試題輸入一個單向連結串列,輸出該連結串列中倒數第k個結點。連結串列的倒數第0個結點為連結串列的尾指標

題目:輸入一個單向連結串列,輸出該連結串列中倒數第k個結點。連結串列的倒數第0個結點為連結串列的尾指標。 分析: 單鏈表只能向後遍歷,不能向前遍歷,尾指標好找,倒數第K個不能從尾指標向前找。 倒的不好找,正的好找,我們只需要知道連結串列的總長度,就可以知道正數第幾個節點(

試題輸入一個十進位制整數,將這個數字轉化成對應的十五進位制數(在十五進制中,A表示10,B表示11,C表示12,D表示13, E表示14),請寫入轉換程式。例如235表示為10A;

如上是本人一位朋友的公司出的研發小測試,小朋友是一臉懵逼啊! 分析:進位制轉換思路:10進位制除以15商和餘數,反覆拿商除以15獲得商和餘數,類推,知道商為0,停止; 以235表示為10A為例分析: 235/15 = 15 餘數10 15/15 = 1 餘數

試題產生一個長度為100的陣列,為陣列中的每一項隨機填充1-100之間的數並且保證不重複

這是一道面試題: 參考網上3種方法,C#實現: 方法一: #region 方法一 //存放1-100個數 int[] num = new int[100]

試題輸入一個整數,輸出該整數二進位制中1的個數。

程式碼:C語言 //輸入一個整數,輸出該整數二進位制中1的個數。其中負數用補碼錶示。 //左移運算子是用來將一個數的各二進位制位全部左移若干位。相當於乘法運算,表示為"<<" //右移運算子是用來將一個數的各二進位制位全部右移若干位。相當於除

試題一個string類

一個string類主要包括建構函式、解構函式、拷貝建構函式和賦值建構函式 (1)建構函式需要注意的是:當建構函式引數為空時,string類中為char* pdata成員,因此在初始化成員列表中需開闢一個位元組的空間,並且賦初始值為‘\0’,因為在字串是以'\0'結尾的,會

C#(.NET)試題一個能自定義輸入命令的表格程序

rom info rate align alloc https att height 寬度 目前為止,已經面試 5 家了。 試題是英文的(後面給出翻譯): you‘re given a task of writing a simple program where an

試題增強一個對象的方法的三種方式

解決 oct rip owa 返回值 dex tty unit web項目 面試題:增強一個對象的方法的三種方式 1. 繼承 使用這種方式必須滿足的條件是:被增強的方法的所在類能被繼承,並且這個對象已經明確知道。 舉例: 有一個接口Person,裏面有一個方法run()

【本人禿頂程式設計師】試題如何設計一個高併發系統

←←←←←←←←←←←← 我都禿頂了,還不點關注! 面試題 如何設計一個高併發系統? 面試官心理分析 說實話,如果面試官問你這個題目,那麼你必須要使出全身吃奶勁了。為啥?因為你沒看到現在很多公司招聘的 JD 裡都是說啥,有高併發就經驗者優先。 如果你確實有真才實學,在網際

java基礎試題try{}裏有一個return語句,那麽緊跟在這個try後的finally {}裏的code會不會被執行,什麽時候被執行,在return前還是後?

nal java pan clas out bsp 出現 可能 inf package com.swift; public class Try_Catch_Finally_Test { public static void main(String[] args

java算法試題排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。選擇冒泡快速集合至少4種方法排序

算法 err div println rda print 算法面試 ++ 快速排序 package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util

試題二叉樹的下一個節點

ret 試題 tree link 同時 pre lin 下一個 color 題目描述:給定一個二叉樹和其中的一個結點,請找出中序遍歷順序的下一個結點並且返回。註意,樹中的結點不僅包含左右子結點,同時包含指向父結點的指針。 思路: //包含指向父節點的指針 //node.n