PowerBI中的权限控制是分层次的,具体请以官方文档为准。但为了便于快速理解,这里特此编制了一个权限结构图:
这里涉及到8个构件,并用一个比喻来理解PowerBI的权限控制,想象一下:你作为自己家的主人,想让陌生人到你家的某个抽屉里拿东西。如下:
因此,这里可以澄清几个重点了:
另外,如要使用行级别安全性的控制,首先必须满足如下条件:
接下来才轮到行级别安全性的控制来接管。
什么是静态设置,就是一旦设置了,就固定了。标准流程如下:
重复上述过程,设置了很多管理区域,并在云端将不同地区的管理成员放入不同的大区角色。 这种静态的设置方法,最大的特点是:
对于这种方案,由于很简单,可以在网上找到大量教程,不再介绍。总之:没有用 USERNAME() DAX 函数 的方案肯定是静态的,也一定不是最佳的。(当然,用了USERNAME() DAX 函数也不一定就是最佳的)
这种方法已经在此前的 PowerBI 实现不同角色看到内容不同支持动态权限管理 已经描述过,其核心在于:
该方案已经足够好用,但本文将做进一步改进,改进成全自动形式并且完全对用户透明的方法。
这又是 OCP(开放闭合原则) 原则的充分体现,即:对扩展开放,对修改关闭。首先,先来体验下这是怎样的效果:
你在惊讶,这没PowerBI什么事啊,没错,确实没PowerBI什么事,因为复杂性全部被封装了,也是目前为止,PowerBI中能实现相对完美的不多的设计。下面来图解这个过程:
这个配置表在多次设计后,已经对操作用户做到了极致的友好:
从这个配置表,用户可以非常容易理解他需要怎么做,为什么不用管PowerBI呢,因为PowerBI的下一次自动刷新会通过数据网关将该配置表重新读入,进而建立新的权限机制,因此,这实现了一种:增加或减少权限配置而不需要编辑PowerBI的文件的巧妙做法。这就诠释了OCP原则,对扩展开放,对修改关闭,这里开放的是用户可以任意扩展配置表的内容,而关闭的是对PowerBI文件的修改,所有的架构设计都应该遵循OCP原则。
下面来详细说明,PowerBI文件中都做了什么来实现这样的动态安全性控制。
首先,看下PowerBI文件的查询结构:
可以看出我们单独设置了权限控制部分的配置表和度量值,来看看权限控制表的实现:
这里对用户的配置,进行了逆透视以及规范化处理,形成了便于在PowerBI中便于使用DAX处理的结构,这个结构是通用的,可以:允许用户配置时任意增加透视列或单元中的项数,配置文件路径以及分隔符全部用参数给出,仍然满足OCP原则。如果要说这里算有难度的地方,就是如何把一个透视表,也单元格内含有多项内容的表格,自动转换为原始的规范化表,这由PowerBI的查询编辑完成。这里比较厚道地全部粘贴如下:
let Source = Excel.Workbook(File.Contents( 权限控制表路径 ), null, true), AccessControl_Table = Source{[Item="AccessControl",Kind="Table"]}[Data], #"Unpivoted Columns" = Table.UnpivotOtherColumns(AccessControl_Table, {"用户名称", "用户账号"}, "权限分类", "拥有权限"), #"Extracted First Characters" = Table.TransformColumns(#"Unpivoted Columns", {{"拥有权限", each List.RemoveItems( Text.Split( _ , 权限控制分隔符 ) , {""} ) }}), #"Expanded {0}" = Table.ExpandListColumn(#"Extracted First Characters", "拥有权限"), #"Changed Type" = Table.TransformColumnTypes(#"Expanded {0}",{{"拥有权限", type text}}), #"Trimmed Text" = Table.TransformColumns(#"Changed Type",{{"拥有权限", Text.Trim, type text}}) in #"Trimmed Text"
然后来到PowerBI数据模型中看看是用怎样的度量值来计算和控制权限的,我们根据需要实现了判断权限的度量值如下:
观察上述两个分别控制产品以及地区的度量值结构,只需要修改最前面两行的实体部分即可,其他部分不做任何改变。这样,当需要判断更多权限的情况产生时,只需要复制和修改这个DAX表达式即可。
这里其实是不满足DRY设计原则的,因为存在大量重复,这也是DAX作为编程方式的边界,它不真正在设计上支持工程化的形式。非常希望微软能在DAX表达式本身加入更多的动态特性。原理上,只需要改进编译器即可,并不是很难的问题,但以M语言加入智能提示的速度来看,不敢奢求了。
然后,在角色中这样控制权限:
由于这个方案已经将实际的权限控制全部交给配置表动态处理,其实已经不需要利用PowerBI的多角色机制了,只需要一个角色,随便起个名字即可,然后使用刚刚的度量值,分别对应要控制的表放入即可,如此简单。
然后就可以看看在Power BI Desktop中的模拟效果,如下:
可以注意到该用户 chujie@excel120.com 的权限完全被限制在和Excel配置文件中完全一致的范围。整套机制堪称完美。我们再到云端来看看实际效果:
用户楚杰被牢牢锁在只有只读权限并被控制了范围的状态下,对此,用户也毫无怨言。再来欣赏下,Excel配置文件是如何可以动态刷新的:
因此,终端用户永远只需要修改Excel文件即可,这种权限的控制,实现了完全和PowerBI本身解耦,是在PowerBI企业级权限控制上,目前为止所见的最佳方式。尤其可以应对大量用户(例如超过100人)的统一在Excel中配置其权限。
在学习PowerBI建立关系时,很多人好奇一个地方:
这个在两个方向上应用安全筛选器是什么意思,在这里的场景下:
会出现两种理解:
如果,用户的需求希望按 1 来,则不需要启用安全筛选,如果希望按 2 来,则需要启用安全筛选。来看看效果:
不启用安全筛选:
启用安全筛选:
这就为企业级安全的精细控制做出了非常准确的约束。
如果可以按照本文的思路非常准确认真的实现配置化的动态权限控制,不难发现:
另外,某些现实的需求在行级别安全性下成了限制,例如:
在行级别安全性下,由于数据已经被筛选,因此无法实现上述需求,需要做一些补充才能完成。例如:再加载一次事实表,单独计算。当然,如果可以重复理解本文思路,也可以完全不使用行级别安全性来控制权限。读者可以自行试验,欢迎探讨。
本文系统全面了描述了企业级全动态的安全性配置解决方案,并使用Excel文件从PowerBI中完全解耦,实现了终端用户只需要配置Excel即可完全复杂的权限配置。正文部分已经将思路和核心逻辑以及核心函数全部贴出,大家可以参考实现。另外,这里已经给出了超过行级别安全性控制的方法,进而可以实现更多的可能性,欢迎交流讨论。