恰逢公司网络故障, JIRA、SVN、ORACLE都无法连接上,那就继续上次的议题吧。
实现原理深入:
- 目标:查看所有招标合同, select * from Documents
- 权限约束场景:
A. 每个用户仅可查看本部门创建的合同: where CreatedOffice in ( CurrentUser.ChildrenOffices)
B. 每个用户仅可查看自己创建的合同: where CreatedBy=CurrentUser.UserId
C.指定权限用户可以查看关联的合同: (需要通过Alt+双击,定义所有的合同权限,否则默认为All可见)
where DocumentId in (select ResourceId in AclParty p where p.PartyId in
( CurrentUser.Offices, CurrentUser.UserId, CurrentUser.Roles, CurrentUser.Groups )
) OR DocumentId NOT IN (select ResourceId in AclParty p )
查看此用户/部门/角色/工作组拥有的合同, 以及未作授权的合同可见。
D. 上述权限的组合
where CreatedOffice in (CurrentUser.ChildrenOffices) and DocumentId in (Resource … in ….AclParty …of ….CurrentUser…)
3. 实施约束:
QueryInfo info = new QueryInfo(“Documents d”);
//IList allDocs = Dao.FindList(info);
仅需设置如下属性, 则上述约束的sql会自动注入到查询条件后。
A. info.AclProperty=”d.CreatedOffice”; (常量检测CreatedOffice)
B. info.AclProperty=”d.CreatedBy”; (常量检测CreatedBy)
C. info.AclProperty=”d.Id”;
D. info.AclProperty=”d.Id,d.CreatedOffice”;
扩展应用:
- 检测用户对某一资源的控制串:
A. bool hasPurview = CurrentUser.GetAclOperation(“ResourceId”,"OperationCode”);
B. btn_Del_.Visible = CurrentUser.GetAclOperation(“DocumentId001”,"Del”);
C. 对于同一资源Id, 一次取出此用户对应的所有OperationCode。
2. 验证用户对某一资源的操作
QueryInfo info = new QueryInfo(“Delete from Documents d”);
info.AddParam(“OfficeId”, CurrentUser.Office);
info.AclProperty=“d.Id”; ///等同于 info.Where.Add(“Id”,"DocumentId in (Resuource …in ….AclParty …of ….CurrentUser…)");
Dao.ExecuteUpdate(info);
上述操作即可完成: 删除所有 本人拥有权限的、且属于本部门的合同。
强制数据权限:
1.QueryInfo无需定义任何AclProperty
2. 通过AOP,在Dao拦截所有QueryInfo
3. 逐一检验QueryInfo的QueryObject, 与AclItem 中的所有Module=QueryObject 的项目比较, 如果
info.QueryObject in (AclItem.ResourceCode) and info.GetOperationCode() == AclItem.OperationCode,
则 info.AclProperty=AclItem.Policy;
4. 自动激发AclProperty校验。
总结:
通过上述步骤, 对数据项进行人工控制、自动注入都是非常方便的。 其控制粒度就是对象的属性。 根据属性在 资源-授权组 的设定, 即可有效的进行数据权限 判断、控制、校验。
但目前对 同一对象 多个属性 叠加 校验时, 叠加策略如何灵活定义(AND, OR) ??
如: 查看 经过总经理审批的 AND 我创建的
查看 经过总经理审批的 OR 我创建的
AclProperty如何扩充足够的语义,以完成完整的Policy设定? 欢迎大家讨论!!