功能許可權和資料許可權管理的實現
1 引言
許可權,可分為“功能(操作)許可權”和資料許可權兩種,在系統中,兩種許可權應當同時有效。例如,在windows系統中,某使用者具有新建一個檔案的功能許可權,該使用者在C盤沒有寫許可權,但在D盤有寫許可權;則該使用者不能把他建立的檔案儲存在C盤而只能儲存在D盤。
在上述例子中,能否建立檔案是由功能許可權來控制的,能否儲存檔案是由資料許可權進行控制的。只有兩者同時有效,使用者的業務才能順利進行。
簡單地說,許可權管理就是對資源的管理。許可權管理的目的就是建立分配資源的規則,以便使用者能夠通過這套規則,獲取他們應該獲得的資源。
1.1 定義
² 功能許可權:
也叫操作許可權,指的是允許或拒絕使用者使用系統提供的某個功能。
² 資料許可權:
指的是允許或拒絕使用者進行某個資料的增刪改查操作。
² 授權:
指的是分配具體的許可權給具體的人。
² 鑑權:
指的是對具體人的行為,根據許可權規則進行合法性鑑別。
1.2 授權的基本原則
對於授權來說,需要定義的有且只有許可權和授權物件兩個要素。簡而述之,對於功能操作就是“什麼功能授權給哪個使用者來操作”
一般情況下,我們並不會對單一的功能/資料進行單使用者的授權管理,因為這樣使用者操作起來顯然非常麻煩。為了方便和簡化操作,一般的授權規則是:
哪些功能/資料授權給哪些使用者
1.3 授權的一般方法
在實際的授權管理中,我們總是根據業務的需求,將一些在業務上不可分割的、需要允許使用者一起使用的功能,組合成一個許可權集合進行統一授權。對於這樣的許可權集合,我們一般稱之為“角色”。也就是說,我們通過角色來定義使用者被允許使用哪些功能和訪問哪些資料。當然,我們一般把功能和資料分開來進行授權,以便獲得更加靈活的許可權規則配置方法,以適應更廣泛的授權需求。
由於某些不同使用者在該業務上需要具有相同的許可權,那麼這些不同的使用者在特定的業務上就具有了共性,可以作為一個抽象的使用者來進行許可權的授予。授權管理使用的抽象的使用者,也就是使用者集合,除了普遍使用的“使用者組”外,還可以引用別的業務中所使用的物件。例如組織機構管理中的“機構/部門”、“職位”和工作流中使用的“崗位”等,在授權管理中都是作為使用者集合使用,本質毫無二致。
通過讓抽象的使用者扮演角色,即可使這個抽象的使用者所代表的真實使用者獲得完成業務所需的許可權。通過這樣的方式,可以簡化授權管理,方便使用者操作。
2 授權管理
將特定的許可權授予特定的人群的過程,我們稱之為“授權”。為了能夠方便地進行授權操作,我們必須要有一個能夠提供合理授權方法的使用者介面。
2.1 功能許可權的授權
對於一個可擴充套件的系統來說,意味著功能是不斷變化的。為了適應這種不能事先確定的變化,必須將功能許可權進行分散管理。分散管理的好處如下:
² 天然地支援業務的動態變化,系統實現簡單。
² 許可權的調整範圍可控制在區域性範圍,方便許可權的管理和操作。
2.1.1 一般許可權的授予
功能許可權是單維度的,可以通過簡單的在功能列表或功能樹上進行勾選來確定一個“角色”所允許的功能操作。然後,讓相應使用者成為該“角色”的“扮演者”。這樣就可以把該角色所允許的功能操作授權給指定的使用者了。
如果需要有更多的不同角色,那麼新建角色,勾選不同的被允許的功能操作,並分別讓相應的使用者成為新角色的成員即可。
2.1.2 例外許可權的授予
如果某個特定使用者張三需要額外的一個許可權,那麼新建一個允許該功能操作的角色,並讓張三成為該角色成員即可使張三擁有額外的許可權。
如果某個特定使用者李四需要比同一專案組的其他人少一個許可權,那麼新建一個拒絕該功能操作的角色,並讓李四成為該角色成員即可使李四不能進行該項操作。因為在鑑權過程中,拒絕的優先順序要高於允許。
2.2 資料許可權的授權
資料在系統中共同的特性有如下維度:
² 業務維度:不同的業務產生不同的資料
² 生產者維度:相同的業務會有多個數據生產者和生產部門
有些業務需要使用者訪問其他業務的資料,或者是其他資料生產者中特定生產者的生產的資料。簡單的說,就是資料許可權的授予必須支援跨業務和跨部門。
2.2.1 一般許可權的授予
由於資料的特殊性質,實際上在有限範圍內的授權比功能許可權的授予更加方便。因為生產部門和生產者具有天然的分類屬性,所以象“本機構”、“本部門”、“本人”這些對生產者維度的進一步抽象就有了用武之地。
在不對業務維度做限定的情況下,就可以配置例如“允許本部門的成員管理(增刪改查)本部門的資料”這樣的許可權規則。那麼對於不同部門的使用者,這條共同的規則所產生的效果並不相同,具體的效果是與使用者所在的部門的業務和產生的資料相對應的。
根據以上分析,我們可以內建一些抽象規則,例如:
² 允許管理本機構(含下級機構/部門)的資料
² 允許管理本部門(含下級部門)的資料
² 僅允許管理本部門的資料
² 僅允許管理本人的資料
² 允許檢視本機構(含下級機構/部門)的資料
² 允許檢視本部門(含下級部門)的資料
² 僅允許檢視本部門的資料
² 僅允許檢視本人的資料
2.2.2 自定義許可權的授予
一般資料許可權的授予只能侷限於符合高度抽象規則所限定的範圍。如果要在這個範圍之外的資料進行授權,例如想讓財務部的人訪問採購部的資料,顯然是一般資料授權所不能支援的。
這個時候,我們就必須要提供使用者在角色中自由定義允許或禁止使用者訪問的資料集的方法。上面說過,一個數據需要在業務和生產者兩個維度上進行描述,才能確定資料。那麼在定義角色所允許訪問的資料集時,因為授權分散在不同的業務中,所以業務是確定的,剩下的就是需要指定一個或多個生產者。在這裡,生產者可以使用抽象方法進行歸納分類。
最後,類同於功能許可權的授權方式,我們把定義好的角色分配給一個抽象的使用者即可將一個自定義的資料許可權授予抽象使用者代表的真實使用者。
3 許可權管理的實現
許可權管理的具體實現方法,離不開資料結構的支援。相對來說,有具體的資料結構,我們也更容易理解許可權的管理機制。在討論許可權之前,我們還需要先了解許可權管理的物件:功能資源和資料資源。這些資源同樣需要一個數據結構去進行定義。
3.1 組織機構和使用者
組織機構表:
[sql] view plain copy- CREATE TABLE Sys_Organization(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
- [SN] BIGINT CONSTRAINT IX_Sys_Organization UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [ParentId] VARCHAR(36), --父節點ID
- [NodeType] INT NOT NULL, --節點型別:1、機構;2、部門;3、職位
- [Index] INT, --序號
- [Code] VARCHAR(32), --編碼
- [Name] NVARCHAR(32) NOT NULL, --名稱
- [Alias] NVARCHAR(16), --別名/簡稱
- [FullName] NVARCHAR(32), --全稱
- [PostId] VARCHAR(36), --崗位ID,字典
- [Validity] BIT DEFAULT 0 NOT NULL, --是否有效:0、無效;1、有效
- [CreatorUserId] VARCHAR(36), --建立人ID
- [CreateTime] DATETIME DEFAULT GETDATE() NOT NULL --建立時間
- )
- GO
使用者表:
[sql] view plain copy- CREATE TABLE Sys_User(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED, --此ID與主資料ID相同
- [SN] BIGINT CONSTRAINT IX_Sys_User UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [Name] NVARCHAR(16) NOT NULL, --使用者名稱
- [LoginName] VARCHAR(36) NOT NULL, --登入名
- [Password] VARCHAR(32) DEFAULT 'e10adc3949ba59abbe56e057f20f883e' NOT NULL, --登入密碼,儲存密碼的MD5值,初始密碼123456
- [Description] NVARCHAR(MAX), --描述
- [BuiltIn] BIT DEFAULT 0 NOT NULL, --是否預置:0、自定;1、預置
- [Validity] BIT DEFAULT 0 NOT NULL, --是否有效:0、無效;1、有效
- [CreatorUserId] VARCHAR(36), --建立人ID
- [CreateTime] DATETIME DEFAULT GETDATE() NOT NULL --建立時間
- )
- GO
3.2 資源
3.2.1 模組和功能
模組表:
[sql] view plain copy- CREATE TABLE Sys_Module(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
- [SN] BIGINT CONSTRAINT IX_Sys_Module UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [ParentId] VARCHAR(36), --父模組ID
- [Level] INT NOT NULL, --模組級別:0、主窗體模組;1、普通業務模組;2、業務子模組
- [Name] NVARCHAR(64) NOT NULL, --名稱
- [Location] VARCHAR(MAX) NOT NULL, --檔案安裝路徑
- [DataTable] NVARCHAR(64), --模組主資料表名稱
- [Description] NVARCHAR(MAX), --描述
- [RegisterTime] DATETIME DEFAULT GETDATE() NOT NULL --模組註冊時間
- )
- GO
模組功能表: [sql] view plain copy
- CREATE TABLE Sys_ModuleAction(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
- [SN] BIGINT CONSTRAINT IX_Sys_ModuleAction UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [ModuleId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_Module(ID) ON DELETE CASCADE NOT NULL, --模組註冊ID
- [Name] NVARCHAR(64) NOT NULL, --名稱
- [SubModuleId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_Module(ID), --子模組ID(功能作為子模組入口時)
- [Description] NVARCHAR(MAX) --描述
- )
- GO
3.2.2 業務資料
物資資料表:
[sql] view plain copy- CREATE TABLE MDG_Material(
- [MID] VARCHAR(36) PRIMARY KEY NONCLUSTERED FOREIGN KEY REFERENCES MasterData(ID) ON DELETE CASCADE, --主資料索引ID
- [SN] BIGINT CONSTRAINT IX_MDG_Material UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [Index] INT, --序號
- [BarCode] VARCHAR(16), --條形碼
- [Brand] NVARCHAR(16), --品牌
- [Model] NVARCHAR(32), --型號
- [Size] DECIMAL(20,6), --規格
- [SizeType] VARCHAR(36) FOREIGN KEY REFERENCES MasterData(ID), --規格單位ID,字典
- [Color] NVARCHAR(8), --顏色
- [Material] NVARCHAR(8), --材質
- [StorageType] VARCHAR(36) FOREIGN KEY REFERENCES MasterData(ID), --儲存方式ID,字典
- [Description] NVARCHAR(MAX), --描述
- [Enable] BIT DEFAULT 1 NOT NULL, --是否可用:0、不可用;1、可用
- [CreatorDeptId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_Organization(ID), --建立部門ID
- [CreatorUserId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_User(ID) NOT NULL, --建立人ID
- [CreateTime] DATETIME DEFAULT GETDATE() NOT NULL --建立時間
- )
- GO
3.3 RBAC模型
3.3.1 角色
角色表:
[sql] view plain copy- CREATE TABLE Sys_Role(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
- [SN] BIGINT CONSTRAINT IX_Sys_Role UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [Name] NVARCHAR(64) NOT NULL, --名稱
- [Description] NVARCHAR(MAX), --描述
- [BuiltIn] BIT DEFAULT 0 NOT NULL, --是否預置:0、自定;1、預置
- [CreatorUserId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_User(ID) NOT NULL, --建立人ID
- [CreateTime] DATETIME DEFAULT GETDATE() NOT NULL --建立時間
- )
- GO
3.3.2 角色成員
角色成員(使用者)表:
[sql] view plain copy- CREATE TABLE Sys_Role_User(
- [ID] VARCHAR(36) PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
- [SN] BIGINT CONSTRAINT IX_Sys_Role_User UNIQUE CLUSTERED IDENTITY(1,1), --自增序列
- [RoleId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_Role(ID) ON DELETE CASCADE NOT NULL, --角色ID
- [UserId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_User(ID) NOT NULL, --使用者ID
- [CreatorUserId] VARCHAR(36) FOREIGN KEY REFERENCES Sys_User(ID) NOT NULL, --建立人ID
- [CreateTime] DATETIME DEFAULT GETDATE() NOT NULL --建立時間
- )
- GO
3.3.3 角色許可權
角色許可權表:
[sql] view plain copy