DQL 实践 —— 数据权限
一、元数据权限(控制表和字段)
WEB系统经常是多用户的,要控制不同用户看到不同范围的元数据信息,有两种实现方式,一是给每种用户创建独立的元数据,部署成多个DQL服务,然后根据当前用户用JDBC连接适用他的 DQL服务即可;二是共用同一个元数据,WEB端筛选元数据信息,去掉不需要看到的表/字段。
多DQL服务
先看第一种,创建manager.glmd、leader.glmd、sales.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,定义Class1和Class2两套元数据范围,在页面上实现切换功能,Class1下只显示Customer、Nation、Region三个表:
定义不同数据范围,以及如何用这些定义筛选元数据,可以在WEB系统中自行实现,也可以借助DQL设计器的字典(*.gdct)功能来定义。
打开元数据文件(TPCH.glmd),然后点击菜单栏Tool -> Create dictionary,就创建出了基于TPCH.glmd的字典文件:
保存为TPCH.gdct:
切换到Class Item标签下,定义Class1、Class2:
字典文件是公开的JSON格式,用文本工具打开,可以看到JSON结构:
现在读取字典文件中的Class1、Class2,即可针对不同用户实施权限控制。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 == 18。dqlQuery.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执行。
英文版