开源 BI 实践:控制数据权限

数据通常不会对所有用户完全开放,BI 系统还要能控制用户的数据访问权限,也就是可以控制某个用户能够查询哪些表和字段,以及还可以通过查询条件控制对表中记录的访问权限。

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

字典文件 (*.dct) 可以设置表和字段的业务名称、设置字段的显示格式,把维度代码对应成名称,此外,字典里还可以对表、字段进行分类管理,按照不同业务主题、权限的需要选出部分表和字段,形成多个分类项,然后 BI 前端通过选用一个分类,就可以控制表、字段的可用范围。

如下图,在 tpch.dct 里,选中“分类项”标签,添加客户分析、供应商分析两个分类,可以看到“客户分析”中选出一些表和字段,排除了与客户分析无关的订单、订单明细等表:

..

然后在 jsp 里如下设置使用客户分析这个分类:

<script>

guideConf.dct="tpch.dct";

guideConf.className = "客户分析";

</script>

再访问 BI 界面,看到只显示“客户分析”分类下的表和字段了:

..

上面的元数据树可以把维表展开,进一步选择维表字段,比如从客户表展开出国家表,国家表再展开出区域表。如果想控制某些维表不再展开,可以在“客户分析”分类下去掉相关维度,如下去掉区域维:

..

再访问页面,看到区域维表已经不能展开了:

..

控制数据 (记录) 权限

比如某用户不能看中东、欧洲的数据,那可以在他的 session 里针对区域表设置隐含的限定条件:
DQLTableFilter f = new DQLTableFilter("default");

f.getFilters().put("region","${T}.R_NAME NOT IN ('MIDDLE EAST','EUROPE')");

ArrayList filters = new ArrayList();

filters.add(f);

session.setAttribute("_raqsoft_filters_",filters);

页面中查询区域、国家时不设置任何条件,但也看到中东和欧洲被屏蔽了:

..

观察 DQL server 控制台的日志,发现查询 DQL 语句确实自动补上了 session 中的限定条件:

..

更进一步,即便查出的信息中不包含区域表,也能自动关联到区域表补上限定条件,如下查询各年订单数量时,能观察到 DQL 中【订单的客户的国家的区域】这个限定条件:
..

..

如果多个表都需要设置限定条件,在 JSP 中书写起来比较啰嗦,可以生成一个可视文件,集中定义各表条件。打开元数据文件 tpch.lmd,系统→生成可视编辑:

..

生成的可视文件保存为 {WEB 根目录}/WEB-INF/files/dql/tpch.vsb,所有表都可以预设限制条件,如区域表设置为 ${T}.R_NAME NOT IN ('MIDDLE EAST','EUROPE'):
..

之后在 JSP 里使用 tpch.vsb 就可以了:
DQLTableFilter f = new DQLTableFilter("default");

f.setVsb("tpch.vsb",request);

不同用户的权限不同,需要设置不同的限制条件,那给每个用户生成一个可视文件,也是比较繁琐,这可以用宏值替换的方式定义条件:

..

不同登录用户共用 tpch.vsb 文件,针对 exclude 宏设置不同的的值即可:
DQLTableFilter f = new DQLTableFilter("default");

f.setVsb("tpch.vsb",request);

f.getParamValues().put("exclude","'MIDDLE EAST','EUROPE'"); //A 用户不看中东、欧洲

f.getParamValues().put("exclude","'ASIA'"); //B 用户不看亚洲

宏太多时,还可以定义一个 json 文件统一设置某用户的所有宏值:
{"MACRO_VALUES":

 {

  "exclude":"'ASIA'"

  ,"macro2":"VALUE2"

  ,"macro3":"VALUE3"

 }

}

这个宏文件存为 {WEB 根目录}/WEB-INF/files/dql/tpch_macro.json,然后在 jsp 里使用它就可以设置上所有宏值了:

DQLTableFilter f = new DQLTableFilter("default");

f.setVsb("tpch.vsb",request);

f.setMacro("tpch_macro.json", null ,request);

后记

要想数据安全,控制数据权限是必要的,在完成权限控制后,用户面对自己的安全数据又需要全权地灵活分析,基于 DQL 容易实现这种灵活的查询分析功能。