PowerBI多表场景下RLS行级别权限管理角色配置问题求助
附言
现有表结构不可修改,允许在视图、Power Query中添加列做调整。
问题说明

尝试将Child表与RLS1、RLS2、RLS3表建立关联,但仅能关联一个RLS表,无法像SQL那样同时关联三个表实现权限匹配。
原设计RLS逻辑
核心调用USERPRINCIPALNAME()函数,预期逻辑如下:
RLS1 = USERPRINCIPALNAME() || RLS2 = USERPRINCIPALNAME() || RLS3 = USERPRINCIPALNAME() || (USERPRINCIPALNAME() = 'tblDimOverride'[Override] && 'tblDimOverride'[Child] = RLS1) || (USERPRINCIPALNAME() = 'tblDimOverride'[Override] && 'tblDimOverride'[Child] = RLS2) || (USERPRINCIPALNAME() = 'tblDimOverride'[Override] && 'tblDimOverride'[Child] = RLS3)
如果支持多表关联,可简化为:
RLS1 = USERPRINCIPALNAME() || RLS2 = USERPRINCIPALNAME() || RLS3 = USERPRINCIPALNAME() || USERPRINCIPALNAME() = 'tblDimOverride'[Override]
问题迭代记录
2021年9月20日补充
尝试在「角色管理」中使用如下逻辑:
... || LOOKUPVALUE([RLS1],'tblDimOverride'[Child],USERPRINCIPALNAME())
需要对RLS1到RLS(n)都应用该逻辑,不想只建立RLS1和Child的关联,运行后报错:does not exist or has no relation to any table that is available in the current context,根源是无法建立Child表与多个RLS表的关联。
2021年9月29日补充

通过LOOKUP把值合并到同一列的方案不符合需求,9月20日的思路最优但无法落地,需要可行解决方案。
可行解决方案
无需修改原有表结构,也不需要建立多表物理关联,采用以下两种方案均可实现需求:
方案1:直接编写无关联依赖的RLS规则
直接在Child表的角色RLS规则中写入以下DAX逻辑即可,不需要额外调整表结构:
VAR CurrentUPN = USERPRINCIPALNAME() // 收集当前用户在3张RLS表中有权限的ChildID集合 VAR DirectAuthChild = UNION( CALCULATETABLE(VALUES(RLS1[ChildID]), RLS1[UPN] = CurrentUPN), CALCULATETABLE(VALUES(RLS2[ChildID]), RLS2[UPN] = CurrentUPN), CALCULATETABLE(VALUES(RLS3[ChildID]), RLS3[UPN] = CurrentUPN) ) // 收集当前用户在Override表中有权限的ChildID集合 VAR OverrideAuthChild = CALCULATETABLE( VALUES(tblDimOverride[Child]), tblDimOverride[Override] = CurrentUPN ) // 匹配当前行是否在权限范围内 RETURN [ChildID] IN DirectAuthChild || [ChildID] IN OverrideAuthChild
注:请将代码中的ChildID、UPN替换为实际表中对应的关联字段名即可。
方案2:Power Query生成统一权限映射表(性能更优)
如果RLS表数量多、数据量大,推荐用Power Query生成独立的权限映射表,不修改原有表结构:
- Power Query中新建空白查询,依次追加RLS1/RLS2/RLS3表,提取
UPN和关联的ChildID两列,将UPN重命名为AuthorizedUPN - 追加
tblDimOverride表的权限数据,提取Override列作为AuthorizedUPN,Child列作为ChildID - 加载该权限映射表,无需与其他表建立物理关联,在Child表的RLS规则中写入以下逻辑即可:
VAR CurrentUPN = USERPRINCIPALNAME() RETURN [ChildID] IN CALCULATETABLE(VALUES(PermissionMap[ChildID]), PermissionMap[AuthorizedUPN] = CurrentUPN)
内容的提问来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

