在查询分析中可以使用.vsb(可视文件)实现权限控制,对于不同的用户可以配置对应的可视文件,使他们在登录WEB后拥有不同的访问权限。
产品中默认提供的查询/分析WEB示例界面,不具备用户权限系统。客户把查询页面引入到自己的系统后,需要在jsp中通过设置Tag属性值或者添加JS API为不同用户设置各自的可视文件,达到权限控制的目的。
除了上述在WEB端设置可视文件,还可以将可视文件部署到DQL SERVER的服务中,使用角色+可视文件+宏文件达到权限控制目的。
本例仅在WEB端配置可视文件,DQL SERVER中没有配置可视文件。
分析控件通过JS API设置可视文件,更多JS API的介绍可参考JS API控制初始化界面小节:
<script>
guideConf.vsb="demo.vsb ";
</script>
查询控件可以通过Tag标签设置可视文件,Tag属性详细介绍请参考《程序员参考》查询分析控件:
<raqsoft:detailQuery
visibility="demo.vsb" //设置可视文件
… …
/>
下面以查询控件为例,用实际场景介绍查询控件权限控制,同理,分析控件也一样,都是动态传值为不同的用户传递不同的可视文件,只不过查询控件是传到Tag标签属性,而分析控件是传到JS API。
查询控件示例:
假如客户系统中有两个用户root和guest。root用户权限最大,可以查询全部指标;guest用户只有部分权限,仅能查看个别表的指标。那么我们就可以通过使用变量传递不同的Tag属性值,达到权限控制的目的。
java代码判断,如果当前用户是root则通过Tag属性传递如下值:
String visibility= request.getParameter( " visibility" );
visibility = "root.vsb";//root.vsb:对元数据中的所有表都可见
如果当前用户是guest则通过Tag属性传递如下值:
String visibility = request.getParameter( " visibility" );
visibility= "guest.vsb";//guest.vsb:仅对元数据中的订单、商品类别和商品表可见
<raqsoft:detailQuery
qyx="<%=qyx %>"
dataSource="<%=dataSource %>"
dictionary=""
visibility="<%=visibility %>"
/>
root用户的查询页面demo如下图:

guest用户的查询页面demo如下图:

产品自带的查询/分析控件jsp示例为:
查询控件:[安装根目录]\report\web\webapps\demo\raqsoft\guide\jsp\qyx.jsp
分析控件:[安装根目录]\report\web\webapps\demo\raqsoft\guide\jsp\olap.jsp
通过上一节的学习我们了解到权限控制就是对不同用户使用不同的vsb可视文件。假如有这样一个销售场景,在多维分析中需要让每个员工只能查询自己的订单情况,这样一来有N个销售代表就要做N份可视文件,制作起来费时费力,有没有什么简单的方法可以不用制作这么多可视文件也能实现这种权限控制呢?
当然,下面以报表[安装根目录]\report\services目录下的datalogic服务为例,使用“DQL宏”解决这个问题。
本例中仅在DQL SERVER中使用可视文件,WEB端无需配置。
第一步:准备可视文件
使用元数据编辑设计器打开报表[安装根目录]\report\web\webapps\demo\WEB-INF\files\dql目录中的可视文件demo.vsb,为订单表添加条件可见表达式,如下图:

表达式使用DQL宏,宏的语法为${宏名称}。宏只能用在条件可见里,其中宏名称就是${}中变量名称,宏值就是${}里面变量的值。
将编辑后的demo.vsb保存到报表[安装根目录]\report\services\datalogic\conf目录。
第二步:编辑宏文件
在宏文件中定义角色对应的宏和宏值,文件名可自定义。文件内容为json字符串,格式为:{"角色名":{"宏名":"字段值"}}。
新建宏文件macros.json,文件编码为UTF-8,内容如下:
{"guest1":{"雇员":"1"},"guest2":{"雇员":"2"}}
同样将宏文件保存到conf目录:

第三步:修改service.xml
修改报表[安装根目录]\report\services\datalogic目录下的service.xml。
在<SERVICE>节点里添加宏文件定义,并在<USERS>节点里定义角色和可视文件。

接下来就可以在使用DQL Server连接时,使用不同的角色传递不同的雇员宏值了。
第四步:配置数据源
在报表[安装根目录]\report\web\webapps\demo\WEB-INF\raqsoftConfig.xml中添加数据源guestDataLogic1、guestDataLogic2。

数据源中的user、宏文件中的角色名以及service.xml中USER的name配置项三者一一对应。
第五步:权限控制
实际应用中,通常由应用系统负责提供当前登录用户的信息,然后就可以根据当前登录的用户,控制该用户只能使用某些数据源。这里以多维分析应用为例,通过使用不同的数据源,来展示权限控制的效果。
启动内置的TOMCAT和DQL Server。
通过http://localhost:6868/demo/raqsoft/guide/jsp/olap.jsp访问多维分析页面,使用guest1角色的数据源guestDataLogic1,查询订单表数据,如下图:

雇员字段使用了显示值。
此时查看DQL Server控制台, DQL语句:
SELECT TOP 1000 T1.订单 订单 ,T1.雇员 雇员 ,T1.签单日期 签单日期 FROM 订单 T1
SQL语句:
SELECT T_1."订单ID" "订单",T_1."雇员ID" "雇员",T_1."签单日期" "签单日期" FROM "订单" T_1 WHERE T_1."雇员ID"=1 LIMIT 1000
从SQL语句中可以看到宏替换的结果。
多维分析页面,使用guest2角色的数据源guestDataLogic2,查询订单表数据,如下图:

DQL Server控制台可以看到DQL语句:
SELECT TOP 1000 T1.订单 订单 ,T1.雇员 雇员 ,T1.签单日期 签单日期 FROM 订单 T1
宏替换后的SQL语句:
SELECT T_1."订单ID" "订单",T_1."雇员ID" "雇员",T_1."签单日期" "签单日期" FROM "订单" T_1 WHERE T_1."雇员ID"=2 LIMIT 1000
说明:
l 当 WEB端与服务端(或嵌入式DQL)分别配置可视文件时,程序会同时合并加载两个文件里的不可视表、字段配置;对于同名表,或同一表下的同名字段,任意一方设为不可见,该表/字段就会不可见,而条件可见会以服务端(或嵌入式DQL)的配置为准。
l 在服务端使用可视文件时,service.xml-<USERS >配置里不同的角色可以使用不同的可视文件,这样在服务端实现上一小节的普通权限控制,那么WEB端就可以不配置可视文件了。
l WEB端和服务端都可以使用可视文件达到权限控制目的,如果服务端的可视文件有修改则需要重启服务。相比较,在服务端使用可视文件更安全,在WEB端使用可视文件更灵活。
其他应用程序连接DQL Server时,可以使用set macro命令动态修改服务中的宏定义,修改后的宏会自动保存到服务/conf目录下的AutoGeneratedMacro.json文件中。
此时需将DQL JDBC所需的datalogic-***.jar、esproc-bin-***.jar 、report-***.jar和json-*.jar放在程序能加载到的路径,获取路径为报表[安装根目录]\report\web\webapps\demo\WEB-INF\lib。
命令详解:
本例中DQL JDBC的url为jdbc:datalogic://127.0.0.1:3366,127.0.0.1:3367/datalogic
(一)使用jdbc修改所有服务器上指定角色的宏:
set macro {用户名:宏组成的json,用户名:json,...} to [host1:port1,host2:port2,...]
示例命令:set macro {root:{\"雇员\":\"4\"}} to [127.0.0.1:3366,127.0.0.1:3367]
(二)将一台服务器上的所有宏集更新到其它服务器:
set macro from [host:port] to [host2:port2,host3:port3,...]
示例命令:set macro from [127.0.0.1:3366] to [127.0.0.1:3367]
上面2条命令中to及其后边的内容可以省略,省略时表示to后面的server来自url里指定的其他server。所以第一条命令可以简化为set macro {root:{\"雇员\":\"4\"}} ,第二条命令可以简化为:set macro from [127.0.0.1:3366]
注意:
使用此方法时,角色必须是管理员,需在service.xml的<USER>中配置admin="true"。
缺省使用service.xml配置的宏文件中的宏,如果使用过set Macro,则使用最近一次set Macro的值。
l 在java中调用DQL,动态修改宏文件示例:
public void testDataServer() {
Connection con = null;
java.sql.Statement st;
try{
Class.forName("com.datalogic.jdbc.LogicDriver");
con= DriverManager.getConnection("jdbc:datalogic://127.0.0.1:3366,127.0.0.1:3367/datalogic","root","root");
//直接创建Statement
st=con.createStatement();
//直接执行语句,操作指定角色的宏
boolean b =st.execute("set macro {root:{\"雇员\":\"5\"}} to [127.0.0.1:3366,127.0.0.1:3367]");
//打印执行结果
System.out.println(b);
}
catch(Exception e){
e.printStackTrace();
}
finally{
//关闭连接
if (con!=null) {
try {
con.close();
}
catch(Exception e) {
System.out.println(e);
}
}
}
}
l 使用集算器动态修改宏文件示例:
数据源定义如图:

SPL示例:
|
|
A |
|
|
1 |
=dqldemos.execute@s("set macro {root:{\"雇员\":\"(1,10)\"}} |
将所有服务器上root角色的宏改为"雇员":"(1,10)" |
|
2 |
=dqldemos.execute@s("set macro from [127.0.0.1:3366] to [127.0.0.1:3367]") |
将127.0.0.1:3366服务器上的所有宏集更新到127.0.0.1:3367服务器上 |