信息系统开发平台OpenExpressApp - 数据权限
功能權限一般放在一般是放在MVC的controller層,在《信息系統開發平臺OpenExpressApp - 功能權限》介紹了OEA基本的功能權限,我們是通過統一配置的。作為數據應用產品來說,數據權限也使很重要的一塊,而數據權限一般放在業務層,但我們也希望能夠通過把權限設定依據放在統一地方由外部來配置數據權限。本篇將介紹一下目前OpenExpressApp對數據權限的支持。
需求
數據權限總的目的:限制某些Role訪問某些數據行,比如限制客戶經理Role只能訪問區域是北京的客戶資料,區域是上海的客戶資料,該Role就不能訪問。
一般場景:
?? 由于目前OEA對組織結構只是簡單的支持,所以還不支持上下級等組織關系引起的數據權限,而先只考慮業務層面帶來的數據權限,如上面的2、3
?
下圖為項目中一個具體案例,以下一個項目信息圖,Project為項目,ProjectPBS為項目的一個計量維度,它關聯到PBS。ProjectPBS下有一些屬性值(ProjectPBSPropertyValue),每個屬性值關聯到之前定義的屬性(PBSProperty)。
以下為系統的一個查詢界面,它左邊導航查詢面板中用到了項目信息。現在需要控制,下面第二張圖中的項目下拉數據需要考慮權限,選擇項目后PBS顯示也需要考慮權限,也就是說獲取的列表數據必須根據權限過濾過。
??
數據權限功能
根據需求,目前只支持對象集合的數據權限過濾,數據權限可能出現以下幾個場景:
- 對象級別
- 屬性級別
- 權限控制類型
- 可讀
- 可寫
- 自定義
目前只支持對象級別,OEA的對象級別的權限是通過控制列表的形式來體現,目前支持前三種,只考慮對象本身設置的數據權限,權限控制類型暫考慮可讀
實現思路
目前實現數據權限基本上有以下方法:
OEA主要考慮通過表達式來設置對象列表數據權限范圍,一般的數據權限設定可以通過內置的表達式來設置,對于復雜的,和業務相關的,可以通過外部擴充表達式函數,由表達式引擎來解析,這樣就可以處理復雜性,又能做到較好的統一管理。
對于復雜應用時,代碼必須能夠控制獲取的數據是按照權限還是忽略權限,所以必須支持代碼級別上的權限控制,也就是說需要寫代碼來控制,對于通用方法,可以通過代碼生成器來生成。
數據權限配置
配置
由于數據權限設定后,需要在代碼中進行相應修改,添加數據檢查步驟,所以配置模塊需要知道系統哪些對象運行設定數據權限。通過給業務對象的則DefaultObject增加InDataPermission屬性來標識對象支持數據權限功能。
[DefaultObject("5D22DEBC-6EA7-45CD-8245-3D9855AE02A6", Catalog = "指標管理",InDataPermission=true), Label("項目信息")]
public partial class Project : GBusinessBase<Project>?
代碼修改
修改前
private void DataPortal_Fetch(){
IsReadOnly = false;
RaiseListChangedEvents = false;
using (var db = Helper.CreateDb())
{
IQuery q = db.Query();
var list = db.Select<Project>(q);
foreach (var item in list)
{
this.Add(Project.GetLazy(item.Id));
}
}
RaiseListChangedEvents = true;
}
修改后:增加檢查數據權限設定表達式步驟,這部分代碼以后也可以通過代碼生成器來生成
[DataPermission]private void DataPortal_Fetch()
{
IsReadOnly = false;
RaiseListChangedEvents = false;
using (var db = Helper.CreateDb())
{
IQuery q = db.Query();
var list = db.Select<Project>(q);
if (list.Count == 0) return;
//考慮數據權限時,添加列表前需要執行數據權限表達式
DataPermissionExprParser oe = new DataPermissionExprParser(list[0]);
foreach (var item in list)
{
Project obj = Project.GetLazy(item.Id);
if (oe.CanRead(obj))
this.Add(obj);
}
}
RaiseListChangedEvents = true;
}
?
注意:由于支持數據權限的業務對象會進行檢查數據步驟,所以對系統性能造成一定影響,所以不需要細粒度控制到行級別數據權限的對象就不要進行數據權限部分的修改
DataPermissionExprParser
在代碼中只需要根據業務對象實例生成一個表達式引擎 DataPermissionExprParser,它會根據類型以及當前用戶所在的角色來組合設定的當前對象的數據權限表達式,
public class DataPermissionExprParser : ObjectExprParser{
string mergedExpr;
public DataPermissionExprParser(object owner)
: base(owner)
{
Guid businessObjectId = new Guid(owner.GetType().GetSingleAttribute<BusinessObjectAttribute>().Id);
string[] exprs = (Csla.ApplicationContext.User.Identity as OEAIdentity).
GetDataPermissionExpr(businessObjectId);
if (exprs.Length == 0)
mergedExpr = String.Empty;
else if (exprs.Length == 1)
mergedExpr = exprs[0];
else
{
mergedExpr = string.Join(") OR (", exprs);
mergedExpr = String.Format("({0})", mergedExpr);
}
if (String.Empty != mergedExpr)
Compile(mergedExpr);
}
public bool CanRead(object owner)
{
return String.IsNullOrEmpty(mergedExpr) || (bool)Evaluate(owner);
}
}
todo
由于目前項目中只需要應用到上面一個場景,由于時間關系,所以不可能全部支持,以下為主要的幾個待做列表:
表達式引擎
Now, 我要為了下午清醒的工作而午休了,關于表達式引擎,大家可以參考《開源 - 輕型的表達式引擎 Flee》
?
更多內容: 開源信息系統開發平臺之OpenExpressApp框架.pdf
?
歡迎轉載,轉載請注明:轉載自周金根 [ http://zhoujg.cnblogs.com/ ]
轉載于:https://www.cnblogs.com/zhoujg/archive/2010/01/19/1643900.html
總結
以上是生活随笔為你收集整理的信息系统开发平台OpenExpressApp - 数据权限的全部內容,希望文章能夠幫你解決所遇到的問題。