DQL 实践 —— 数据权限

一、元数据权限(控制表和字段)

WEB系统经常是多用户的,要控制不同用户看到不同范围的元数据信息,有两种实现方式,一是给每种用户创建独立的元数据,部署成多个DQL服务,然后根据当前用户用JDBC连接适用他的 DQL服务即可;二是共用同一个元数据,WEB端筛选元数据信息,去掉不需要看到的表/字段。

DQL服务

先看第一种,创建manager.glmdleader.glmdsales.glmd,部署成三个DQL服务:

..

然后WEB端改JDBC URL就可以了:

String url = "jdbc:esproc:dql://127.0.0.1:3368/Manager";

String url = "jdbc:esproc:dql://127.0.0.1:3368/Leader";

String url = "jdbc:esproc:dql://127.0.0.1:3368/Sales";

共用元数据

针对元数据TPCH.glmd,定义Class1Class2两套元数据范围,在页面上实现切换功能,Class1下只显示CustomerNationRegion三个表:

..

定义不同数据范围,以及如何用这些定义筛选元数据,可以在WEB系统中自行实现,也可以借助DQL设计器的字典(*.gdct)功能来定义。

打开元数据文件(TPCH.glmd),然后点击菜单栏Tool -> Create dictionary,就创建出了基于TPCH.glmd的字典文件:

..

保存为TPCH.gdct

..

切换到Class Item标签下,定义Class1Class2

..

字典文件是公开的JSON格式,用文本工具打开,可以看到JSON结构:
..

现在读取字典文件中的Class1Class2,即可针对不同用户实施权限控制。dqlQuery.jsp中这段代码会读出TPCH.gdct,提供给前端Javascript使用:

<script language=javascript>

<%

String[] infos = DqlUtil.getDqlInfo(dataSource,"TPCH.gdct","", request);

out.println("var lmdStr = \"" + infos[0] + "\"");

out.println("guideConf.dictionary = \""+infos[1]+"\";");

%>

</script>

二、数据权限(控制表内记录)

同一个表中,希望不同用户看到不同数据。比如某人只能看中国和法国客户的数据,这要求涉及到客户表查询时,拼出来的DQL语句将自动补上权限条件:Customer.NATIONKEY == 6 OR Customer.NATIONKEY == 18dqlQuery.jsp中增加下面这段JAVA代码即用于把这个隐含条件设置到当前登录用户的session里:

<%

ArrayList filters = new ArrayList();

session.setAttribute("_raqsoft_filters_",filters);

DQLTableFilter f = new DQLTableFilter("default","TPCH");

filters.add(f);

f.getFilters().put("Nation","${T}.NATIONKEY==6 OR ${T}.NATIONKEY==18");

%>

然后再查询客户表:

..

尽管界面用户没有设置任何条件,但实际查询时,看生成的DQL已经自动补上了权限条件:
..

为了容易理解,这里把生成的DQL展示到了前端观察效果,常规的WEB系统会在服务器端直接生成带有权限控制的DQL执行。