数据分析的权限控制
【摘要】
自助分析很方便,可以随便获得自己想要的数据,但权限也很重要,不可以随便到让人看到不该看的东西。需要不同的人登录进来看到不同的数据,同时还想要制作简单方便,那该怎么办?不用怕,这里有办法!数据分析的权限控制
哈哈哈哈,打不过我吧,没有办法我就是这么强大,哈哈哈哈,追不上我吧,没有办法被我打败啦,哈哈哈哈,看不见我吧,分析权限根本没在怕!
所谓数据分析的权限控制,就是指针对不同的用户分别配置不同的访问规则,使他们在登录后看到的数据不一样。有些东西不是你想看,想看就能看的,想看还得问问俺老孙答不答应…
首先我们来捋捋分析的权限是如何体现在数据中的。
一、分析中的用户权限
在很多应用系统中,经常有两个典型的用户,root 和 guest。对于数据分析来说,root 用户权限最大,可以查询全部表的信息; guest 用户只有部分权限:只能查看个别表的信息。例如:
root 用户的查询页面 demo 如下图:
guest 用户的查询页面 demo 如下图:
怎么样,大不相同吧,guest 们是不是有种被“歧视”的感觉?那么,是怎么做到让你看啥你就只能看啥的呢?其实并没那么奇妙,说白了 root 和 guest 用户不同的权限,只是因为对应了不同的可视文件(后缀名为 vsb),而 vsb 文件中一些表和字段的可见性设置就是决定权限的最根本因素。具体而言,其中对于表的可见性又分为可见、不可见或者条件可见。
可视文件?什么鬼?——不要着急,接下来就教你制作可视文件。
二、使用可视文件控制分析权限
同学们可以翻到《当多维分析碰到预定义语义》,回顾一下如何创建元数据文件,然后,我们就可以继续讲解如何创建可视文件了。
在菜单栏中点击【系统】-【导入元数据】,将元数据文件中的表导入。
下面用 root.vsb 和 guest.vsb 给大家板书一下。敲黑板,注意了…
首先编辑 root 用户的可视文件 root.vsb,对于 root 用户我们可以使他看见所有表的信息所以对每一个表我们都给他可见的权限:
然后再编辑编辑 guest 用户的可视文件 guest.vsb。对于 guest 用户,诸如 vip 客户等一些表不想让他看到,所以将这些表等设为不可见:
“表可见性”设置为可见时,用户就可以正常查询该表的数据。而设置为不可见时,在查询该表数据时就会报错。如果设置为条件可见,那么将根据设定的条件,在查询表的数据时强制过滤。这样,通过使用不同的可见性配置文件,就可以使不同用户浏览到的记录不同了。
接下来的问题来了,怎么使用这个可见性配置文件呢?简单地说,就是通过 Tag 属性传递。不过,润乾官方提供的只是查询工具,本身不具备用户权限系统。因此,客户在把查询页面引入到自己的系统后,还需要在相应的 jsp 文件中的 java 代码里根据当前用户准备不同的 Tag 属性值,从而达到权限控制的目的。(关于 Tag 属性的详细介绍需要同学们去自学《程序员参考》查询分析控件。)
例如,如果当前用户是 root ,那就通过 Tag 属性传递如下值:
String visibility = “root.vsb”;//root.vsb: 对元数据中的所有表都可见
而如果当前用户是 guest 则需要通过 Tag 属性传递如下值:
String visibility= “guest.vsb”;//guest.vsb: 仅对元数据中的订单表、 产品类别和产品表可见
然后,再用下面的标签就可以了。
润乾报表提供了 qyx.jsp 页面,直接把这个放进去即可。
三、使用宏灵活控制分析权限
现在我们知道了,想要完成权限控制,只需要制作不同的 vsb 文件就可以了。但是实际场景中真的要这么实现就很复杂了。例如在这样一个销售场景中,要求每个员工只能查询自己的订单情况
如果 ** 按照上面的思路:** 有 N 个销售代表就要做 N 份可视文件,拿某个销售代表“李芳”为例,需要把订单表的“表可见性”设置为“条件可见”,并输入相应的条件:
那么当李芳查询的时候在 WEB 端的结果就会像下面这样:
不过,如果真要这么做,那么有多少个雇员就要做多少个可视文件,那岂不是废了老劲了?这时候我们就该想有没有哪个大神能来帮帮我们了……
不用急!找到了润乾报表中“宏”一切就迎刃而解了。
宏可以实现动态条件,对于这个实际场景问题,一个可视文件就可以轻松解决:
首先,我们要知道宏只能用在条件可见里,其中宏名称就是 ${} 中变量名称(这个例子中,宏名称就是“雇员”);宏值就是 ${} 里面变量的值,在实际执行中,系统会用接收到的宏值替换掉宏名称。接下来我们就通过两个场景看看宏值怎么传递的:
场景一:某个雇员登录
在使用了宏之后,系统会利用宏拼接查询条件:
SELECT * FROM 订单 where 雇员 ID = ${雇员}
假设登录的雇员为“李芳”,从登录的 session 界面获取到雇员值为“李芳”的雇员 ID 为 3,将宏值 3 传递进去后就会得到:
SELECT * FROM 订单 WHERE 雇员 ID = 3
为了把正确的宏值传递过来,就需要程序猿带上我们的 Java 代码上场了。在集成到应用系统后,应该由应用系统负责提供当前登录用户的信息,通过 session 传递过来。例如下面 getParamValues().put() 方法。(例子中为了演示直接在 jsp 写了固定值,需要手动改这个值来模拟不同登录用户)
场景二:某个经理登录
我们还是将条件拼接上……
不过不对呀,好像不符合要求呀,我们想要的是经理看到所有员工的订单信息,员工只能看到自己的订单信息。这个宏似乎解决不了问题了——没关系,没什么是多加一个宏解决不了的问题:
上图的代码首先从登录的界面获取到登录者雇员 ID,判断是否是经理 ,如果是经理用户登录,就将经理宏的值设置为 1=1,使得所有数据都满足“1=1 or 雇员 ID= 登录用户 ID”,也就查出所有的数据了。
而如果是普通员工登录,就将经理宏的值设置为 1=0,这样对于“1=0 or 雇员 ID= 登录用户 ID”来说,只有登录用户的 ID 满足条件,也就限制普通员工用户只能看自己的数据了。
假设登录的是郑建杰经理,在拼接条件并传递宏值后,SQL 为:
SELECT * FROM 订单 WHERE 1=1 or 雇员 ID = 5
查询时就可以看到所有雇员的订单信息:
四、DQLTableFilter 对象简述
在上面的代码中,我们用到了 DQLTableFilter 对象。每个 DQLTableFilter 对象中存储了多个表的权限条件(也就是 vsb 里的可视条件),同时也存储了一套宏的具体值。在 session 里可以设置多个 DQLTableFilter 对象,给不同权限的人使用。具体选用哪个 DQLTableFilter 对象,是通过它的名称控制的,默认的是“default”。在拼 SQL 的时候,就会自动追加涉及到的表的权限条件,同时替换宏值。这样,当有用户登录时,可以从 session 中获取到当前登录用户的 DQLTableFilter 对象,其中包括和当前用户匹配的一套宏值,这样在条件拼接时默认拼接当前用户的这套宏值,这样就可以简单实现权限分配了。
当然一个宏值,不仅限于是一个固定的字段值,也可以是字段名、比较符、字段值等任何内容,只要确保可视条件里的宏被宏值替换后,是一个合法的条件表达式即可。
不用 N+1 个可视文件,不用 N+1 个可视条件,只要一个可视文件,只要一个可视条件,就这么 easy,有了可视文件,老板再也不用担心角色分配了,有了“宏”,员工再也不用担心制作可视文件了。
五、针对字段控制权限
到这里并没有结束,权限控制不仅局限于表还可以深入到某个表中的某个字段。我们继续举栗子,假设不想让“赵军”看到”上级”列,只需要在不可视字段中添加上“上级”字段即可:
此时 web 端,分析雇员表中“赵军”(ID=200005)就不会看到“上级”信息:
看到这里的宝宝相信已经 get 到了一项新技能,开始了吗?奥,已经结束了,如果新技能还没有 get 过瘾,就赶紧来润乾报表《分析教程》入坑吧…
上面代码里哪块用了 DQLTableFilter?没看到
三、使用宏灵活控制分析权限中条件控制语句不对,应该为:${T}. 雇员. 雇员姓名 =‘李芳’