如何为DAX计算表MyCalculatedTable应用RLS行级别安全?
问题描述
我创建了如下DAX计算表:
MyCalculatedTable = DISTINCT ( SELECTCOLUMNS ( FILTER ( 'Dim A', LEFT('Dim A'[Group],1) = "B" && LEFT('Dim A'[Id],1) <> "C" && 'Dim A'[Code Type] IN {"A", "Y"} ), "Group", 'Dim A'[Group] ) )
我已在Dim A及其关联的事实表上应用了RLS行级别安全,但该计算表是在数据加载/刷新时生成的,而非查询时动态生成,因此无法自动继承底层表的RLS规则。
我计划在MyCalculatedTable与Dim A之间基于Group列建立1对多关系,设置交叉筛选方向为“双向”并勾选“在两个方向应用安全筛选器”,同时我有一个基于该计算表的度量值:
Amount Paid = CALCULATE ( SUM('Fact A'[Amount Paid]), FILTER ( 'Fact A', RELATED('Dim B'[Invoice Number]) IN VALUES('MyCalculatedTable'[Group]) ) )
我猜测报表中度量值计算时RLS会自动生效,因为度量值是基于用户可见数据实时计算的,RLS会在此阶段强制执行。请问该方案是否可行?正确的实现方式是什么?
解答
方案可行性分析
你的方案不可行,核心问题在于:
MyCalculatedTable是加载时生成的静态表,包含所有符合过滤条件的Group值,不受RLS限制。即使建立双向关系并开启安全筛选,静态表本身的数据不会被RLS过滤,导致用户可能看到超出权限范围的Group对应的计算结果。- 度量值里的
VALUES('MyCalculatedTable'[Group])会返回该静态表的所有Group值,而非用户在Dim A中有权限看到的子集,RLS无法在这个环节生效。
正确实现方式
要让计算逻辑适配RLS,需要避免使用静态计算表,改用动态计算逻辑替代:
方式1:用度量值直接过滤(推荐)
移除MyCalculatedTable,将原计算表的过滤逻辑整合到度量值中,利用RLS对Dim A的限制自动生效:
Amount Paid = CALCULATE ( SUM('Fact A'[Amount Paid]), -- 原计算表的过滤条件 LEFT('Dim A'[Group],1) = "B", LEFT('Dim A'[Id],1) <> "C", 'Dim A'[Code Type] IN {"A", "Y"} )
这种方式下,度量值会在查询时基于用户有权限访问的Dim A数据动态计算,RLS规则会直接作用于Dim A,进而过滤Fact A的数据。
方式2:改用动态计算逻辑复用过滤规则
如果需要复用Group的过滤逻辑,可以在度量值中使用虚拟表,而非静态计算表:
先创建一个返回符合条件且受RLS限制的Group集合的度量值:
Valid Groups = CALCULATETABLE ( DISTINCT('Dim A'[Group]), LEFT('Dim A'[Group],1) = "B", LEFT('Dim A'[Id],1) <> "C", 'Dim A'[Code Type] IN {"A", "Y"} )
然后在主度量值中引用这个集合:
Amount Paid = CALCULATE ( SUM('Fact A'[Amount Paid]), 'Dim A'[Group] IN [Valid Groups] )
这种方式同样是在查询时动态计算,会自动继承Dim A的RLS规则。
补充注意事项
- 避免使用静态计算表承载需要受RLS限制的维度数据,因为静态表不会在查询时重新计算,无法适配用户权限。
- 确保
Fact A与Dim A的关系配置正确,RLS会通过关系自动传递到事实表,无需手动在事实表中重复设置RLS规则(除非有额外的事实表级权限限制)。
内容的提问来源于stack exchange,提问作者user9517769
相关产品推荐
相关产品推荐

