随笔-11  评论-16  文章-1  trackbacks-0

第四章

细粒度数据查询权限

(上)

 

 

通过基于角色访问控制,我们可以控制哪些人具有某种权限。比如总公司员工柴其贵、分公司员工李朵朵和营业部员工贾志宏,三个人都具有访问“查询员工”页面权限。

但,由于他们三人所在公司级别不同(总公司、分公司和营业部),进入查询员工页面,系统展示出来的员工数据应该是不同的。 

此类数据查询权限,在业务系统里面随处可见。毕竟 N 多操作,都起源于查询。连增加数据操作都有,比如增加表单的某个下拉框内容,可能来自数据库查询。 

数据查询权限,包括 2 个纬度:行级和列级。

现有方案

常见拼凑 SQL

常见做法是,采用 if else 做判断,决定执行那条程序分支,也就是 SQL

String sql=””;
if( user.getCompanyLevel()==Constants.总公司 ) {
    sql
=”select * from demouser u, company c where u.companyId=c.id”; //查询所有员工
else if( user.getCompanyLevel()==Constants.分公司 ) {
    String currentUserCompanyId
=user.getCompanyId();
    sql
=” select * from demouser u, company c where u.companyId=c.id and c.id”= currentUserCompanyId + “ or c.pid=+currentUserCompanyId; //查询本分公司及下属营业部员工
else if( user.getCompanyLevel()==Constants.营业部 ) {
    String currentUserCompanyId
=user.getCompanyId();
    sql
=” select * from demouser u, company c where u.companyId=c.id and c.id”= currentUserCompanyId; //查询本营业部员工
}

变通方法

也有不少开发者对上述方法做了改进,我了解到如下改进方法:

1. 采用 AOP 技术,向 find/select 模型注入 where 条件;

2. SQL 语句全部提取出来,集中保存在某个 SQL 配置文件里面,类似 HIBERNATE 那样。

 

上述方法,都不能减少 if else 判断,只是把 SQL 语句做了转移。 AOP 注入方式,将 if else 判断从模型层转移到注入层。集中提取 SQL 方式,只是将 SQL 转移到统一的保存文件, if else 依然转移不掉。

 

关于列级控制、分页查询和自定义条件查询,那就更麻烦了,在此不做叙述。

如果使用 Metadmin

在设计 Metadmin 之初,我们确定了这些目标:

1. 将行列级授权逻辑、 if else 判断全部从业务代码中剥离出去,达到权限与业务完全解开耦合;

2. 提供 API 供业务方法调用,通过该方法获取该用户具有权限查询的数据;

3. 整个过程不要编码,也不要 XML ,通过界面设计出来,并且每个查询逻辑设计完毕,可以立即在线测试,保证查询逻辑无误。

 

为此, Metadmin 提供如下服务:

1. Metadmin 提供数据查询 API :告诉 metadmin ,当前是谁想要查什么数据, metadmin 就能返回该用户具有权限查询的数据;

2. Metadmin 提供的 API 支持分页和自定义条件查询,当然这一切都是在该用户的授权范围内;

3. 权限设计器,通过设计器展现出业务数据库表,运用鼠标拖拽等操作把查询逻辑设计出来,并可以在线测试;

4. 支持复杂、特定数据库逻辑手工输入 SQL ,调优性能。

 

以下演示来自 metadmin 下载包里面包含的演示示例,可以在 www.metadmin.com 下载 Metadmin 安装程序包。

 

API

MetadminService 类:

static QueryResult

query (int privilegeId, User  user, java.util.Map context) 
          评估查询授权策略,返回查询结果。

static QueryResult

query (int privilegeId, User  user, java.util.Map context, CustomizedWhere  where) 
          评估查询授权策略,返回查询结果。

static QueryResult

query (int privilegeId, User  user, java.util.Map context, CustomizedWhere  where, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static QueryResult

query (int privilegeId, User  user, java.util.Map context, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static int

queryCount (int privilegeId, User  user, java.util.Map context) 
          评估查询授权策略,返回匹配记录的个数。

static int

queryCount (int privilegeId, User  user, java.util.Map context, CustomizedWhere  where) 
          评估查询授权策略,返回匹配记录的个数。

 

WebMetadminService 类,为 WEB 程序定制的类,从 HttpRequest 自动读取当前用户:

static java.util.Collection

query (HttpServletRequest req, int privilegeId) 
          评估查询授权策略,返回查询结果。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, CustomizedWhere  where) 
          评估查询授权策略,返回查询结果,支持分页。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, CustomizedWhere  where, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, java.util.Map context) 
          评估查询授权策略,返回查询结果,支持分页。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, java.util.Map context,CustomizedWhere  where) 
          评估查询授权策略,返回查询结果。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, java.util.Map context,CustomizedWhere  where, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static java.util.Collection

query (HttpServletRequest req, int privilegeId, java.util.Map context, int first, int max) 
          评估查询授权策略,返回查询结果,支持分页。

static int

queryCount (HttpServletRequest req, int privilegeId) 
          评估查询授权策略,返回匹配记录的个数。

static int

queryCount (HttpServletRequest req, int privilegeId, CustomizedWhere  where) 
          评估查询授权策略,返回匹配记录的个数。

static int

queryCount (HttpServletRequest req, int privilegeId, java.util.Map context) 
          评估查询授权策略,返回匹配记录的个数。

static int

queryCount (HttpServletRequest req, int privilegeId, java.util.Map context,CustomizedWhere  where) 
          评估查询授权策略,返回匹配记录的个数。

 

业务数据库

第一章讲解了 Metadmin 对于数据库的分类:权限数据和业务数据,两者保存在不同 schema 里面。

WEB-INF/metadmin/datasources.xml

<?xml version="1.0"?>
<datasources>
    
<datasource name="metadmin" configFile="metadmin.properties"/>
    
<datasource name="mydemo" configFile="mysql.properties" schemas="mydemo, metadmin"/>
</datasources>

 

name=”mydemo” 的数据源表示业务数据源,具体配置信息在 mysql.properties 文件里面,打开设计器时,只展示该数据库的 mydemometadmin 两个 schema 数据库表和视图。

具体数据源配置信息,参阅: http://www.metadmin.com/doc/main.html#数据源 2.6

数据查询设计器

在打开数据查收设计器之前,开发者先准备好 JavaBean ,也就是打开把查询出来的数据保存到哪个 Java 值对象。演示程序提供了 Employee ,将查询出来的数据保存到该 JavaBean 里面。

Employee.java

package org.back.demo;

import java.util.Date;

public class Employee {
    
private int id;
    
private int companyId;
    
private int departmentId;
    
private String loginName;
    
private String name;
    
private String password;
    
private String companyName;
    
private String departmentName;
    
private int isManager;
    
private Date hireDate;
    
// … get/set methods…
}

 

启动 web 服务器,在浏览器输入: http://localhost:8080/mydemo/metadmin/designer

(假定您发布的 web contextmydemo ,且服务器端口是 8080

 

打开左边条形框里面的“数据查询”,在树上右击,选择“新增数据查询”。如图示:

 

在弹出的框里面输入相关信息,如图示:


我们先新建总公司用户查看数据的 SQL ,分公司和营业部用户查询 SQL 以及怎样与业务系统集成,由于篇幅关系,下章讲述。

 

在数据查询树上,单击“查询所有员工”,系统自动展现数据查询设计器。

然后按照如下步骤操作:

1.  展开 mydemo schema ,展开表;

2.  双击 company, department, demouser 表,因为要查询这三张表;

3.  勾选 companyname 字段, departmentname 字段,勾选 demouser 表所有字段;

4.  在映射类里面,输入 org.back.demo.Employee

5.  检查下面的字段映射是否有误,修改 company 表的 name 映射属性为 companyName ,修改 department 表的 name 映射属性为 departmentName

如图示: 

到此,设计还差一个步骤,设置 where 条件。本查询 where 条件是 3 张表关联。

按照如下步骤操作:

1.  点击设计器下方的“ WHERE ”标签页

2.  右击条件组,选择“新增二元条件”;

3.  点击第一个字段节点,在右边选择“ company.id ”也就是 company 表的 id 字段;

4.  然后,设置第二个字段为“ demouser.companyId ”字段;

5.  右击条件组,选择“新增二元条件”;

6.    将第一个字段选择为“ department.id ”,第二个字段选择为“ demouser.departmentId ”。

至此,三表关联完毕。也就是完成 SQL company.id=demouser.companyId and department.id=demouser.departmentId

如图示:

 

现在,我们可以测试了!选择设计器下方“测试”标签页,点击控制台执行小图标。 Metadmin 将显示该 sql 语句能查询的数据,行列级!

如图示:

至此,我们完全放心该 SQL 语句没有任何问题。点击“保存”图标,保存设计结果。 

下章,讲解其他 SQL 还有怎样与业务系统集成。

posted on 2009-06-19 11:52 细粒度权限管理 阅读(2353) 评论(2)  编辑  收藏

评论:
# re: 《玩转细粒度权限管理》 四,细粒度数据查询权限(上) 2009-06-19 12:16 | 找个美女做老婆
不错不错,收藏了
Java乐园 技术交流社区:http://www.javaly.cn
Java乐园 群号:15651281
验证消息 : Java乐园  回复  更多评论
  
# re: 《玩转细粒度权限管理》 四,细粒度数据查询权限(上) 2009-06-19 12:17 | 找个美女做老婆
能把原代码共享出来吗?

Java乐园 技术交流社区:http://www.javaly.cn
Java乐园 群号:15651281
验证消息 : Java乐园  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: