Power BI 中的默认筛选器 - 未通过 LOOKUPVALUE 应用行级安全性
Default filter in Power BI - Row Level Security not applied through LOOKUPVALUE
TL;DR:当使用 LOOKUPVALUE()
对抗具有行级别安全性的 table 时,不应用 RLS 并且可以看到所有值
我需要根据用户在 Power BI 报告中选择 'default' 值(位置)。
我正在针对 Azure Analysis Services(表格模型 1400)进行报告
在 Power BI 中实现默认值的方法似乎是将值动态重命名为静态值,然后选择该静态值作为筛选器。
所以
- 用户 Bob 有默认位置 Location1 所以当他登录时他应该看到他的位置
- 用户 Joe 有默认位置 Location2 所以他应该在这个位置过滤
诀窍在于,他们可以选择另一个位置,看看他们是否喜欢
我尝试的第一件事是直接在行级表达式上使用 USERPRINCIPALNAME()
但我得到
...USERNAME and USERPRINCIPALNAME functions are not supported in calculated tables/columns. These functions may only be used in measures or in the AllowedRowsExpression
所以接下来我想我会将 RLS 应用于不同的 table 并查找它,如下所示:
我从名为 Location
的数据库中加载了一个 table,它列出了所有位置。
我有一个名为 MyLocation
的独立 table,它是 Location
的副本。 MyLocation
是使用此 DAX 生成的:
=SUMMARIZE(Location,Location[LocationKey],Location[Location Name])
(注意我也试过 table 基于数据,而不是 DAX)
MyLocation
也像这样应用了动态行级安全性:
=(
[LocationKey]
=
LOOKUPVALUE(
'Employee[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME())
)
当我在 Power BI 中查看 MyLocation
时,我可以看到应用了 RLS - 只能看到一个位置。这与 Location
形成对比,我可以在其中看到所有位置(未定义 RLS)
接下来,我在 Location
中添加了一个列(行级表达式),以选择使用行级安全性评估的这个 'single' 位置:
=LOOKUPVALUE(
'MyLocation'[Location Name],
'MyLocation'[LocationKey],
'Location'[LocationKey]
)
它在 LocationKey 上匹配,但对于已通过 RLS 删除的记录,应该没有匹配项。
然而,当我测试最后一列时,RLS 被忽略,所有位置都通过。
我可以在 Power BI 中看到 table 就在我面前:
MyLocation 看起来像这样:
(已应用 RLS)
Location
==========================
Location 3 Location 3
位置 看起来像这样:
(未应用 RLS,但为什么其他位置不为空?)
Location LookupValue
==========================
Location 1 Location 1
Location 2 Location 2
Location 3 Location 3
Location 4 Location 4
Location 5 Location 5
...........
....
我希望 位置 看起来像这样:
Location LookupValue
==========================
Location 1 blank
Location 2 blank
Location 3 Location 3
Location 4 blank
Location 5 blank
...........
....
所以看来不管你用什么技巧,你真的不能连续使用 USERPRINCIPALNAME()。
我也试过将 USERPRINCIPALNAME()
定义为一个度量并使用它,但也失败了(现在不记得错误了,但我也会重试)
我也尝试过使用 'standalone parameter' table 来打开和关闭 RLS,使用 SELECTEDVALUE
但是参数 table 中的过滤值从未出现。 ISFILTERED
总是 returns false 尽管 table 被过滤了。
到目前为止这对我有用:
objective 是让给定用户自动看到他们自己的位置,但可以选择查看其他位置。
我尝试了很多东西,但最终我只是根据 table 这一事实创建了单独的措施,直接引用 USERPRINCIPALNAME
即这显示了相对于用户位置的位置总单位,相对于其他所有单位显示为零。
My Location Units:=
CALCULATE(
SUM([Units]),
FILTER(
'Location',
'Location'[LocationKey]=
LOOKUPVALUE(
'Employee'[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME()
)
)
)
然后我想:我不能只在维度上使用它吗?
Is My Location:=
CALCULATE(
IF(ISBLANK(MAX('Location'[LocationKey])),"No","Yes"),
FILTER(
'Location',
'Location'[LocationKey]=
LOOKUPVALUE(
'Employee'[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME()
)
)
)
虽然我需要在行级别使用它,但它似乎可以工作,即使它是一个度量。
它使用CALCULATE(<expression>,FILTER(<table>,<expression>))
FILTER
部分做用户级过滤
表达式部分将其变为YES/NO
我可以使用它在 Power BI 中进行过滤,如果需要,我可以只选择当前用户的位置。
我怀疑所有这些表达式都不能写得更简单。不吝赐教
我仍然不知道为什么 LOOKUPVALUE
不遵守 RLS。我想知道是否可以,但我做错了什么,或者是否没有。
我明白你的意思了。 LOOKUPVALUE
似乎可以绕过 RLS 未经过滤地访问您的 table。我建议将此作为错误报告给 Microsoft。
在你的报告中,我建议使用这种形式的措施:
Measure =
VAR EmployeeLocation =
LOOKUPVALUE(Employee[LocationKey],
Employee[UserPrincipalName],
USERPRINCIPALNAME())
RETURN IF(ISFILTERED(Location[Location]),
<expression>,
CALCULATE(<expression>,
FILTER(Location, Location[LocationKey] = EmployeeLocation)))
这样,当 Location
未过滤时,它应该默认计算 EmployeeLocation
的值,否则将正常运行。
据我了解,Lookup[LookupValue] 是一个列(不是度量),使用您的第三个代码片段:“=LOOKUPVALUE( ...”
当您刷新模型时,计算列的结果就会具体化。它们不受在查询时应用的 RLS 的影响,就在计算度量之前。
这不是特定于 LOOKUPVALUE 函数。
TL;DR:当使用 LOOKUPVALUE()
对抗具有行级别安全性的 table 时,不应用 RLS 并且可以看到所有值
我需要根据用户在 Power BI 报告中选择 'default' 值(位置)。
我正在针对 Azure Analysis Services(表格模型 1400)进行报告
在 Power BI 中实现默认值的方法似乎是将值动态重命名为静态值,然后选择该静态值作为筛选器。
所以
- 用户 Bob 有默认位置 Location1 所以当他登录时他应该看到他的位置
- 用户 Joe 有默认位置 Location2 所以他应该在这个位置过滤
诀窍在于,他们可以选择另一个位置,看看他们是否喜欢
我尝试的第一件事是直接在行级表达式上使用 USERPRINCIPALNAME()
但我得到
...USERNAME and USERPRINCIPALNAME functions are not supported in calculated tables/columns. These functions may only be used in measures or in the AllowedRowsExpression
所以接下来我想我会将 RLS 应用于不同的 table 并查找它,如下所示:
我从名为 Location
的数据库中加载了一个 table,它列出了所有位置。
我有一个名为 MyLocation
的独立 table,它是 Location
的副本。 MyLocation
是使用此 DAX 生成的:
=SUMMARIZE(Location,Location[LocationKey],Location[Location Name])
(注意我也试过 table 基于数据,而不是 DAX)
MyLocation
也像这样应用了动态行级安全性:
=(
[LocationKey]
=
LOOKUPVALUE(
'Employee[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME())
)
当我在 Power BI 中查看 MyLocation
时,我可以看到应用了 RLS - 只能看到一个位置。这与 Location
形成对比,我可以在其中看到所有位置(未定义 RLS)
接下来,我在 Location
中添加了一个列(行级表达式),以选择使用行级安全性评估的这个 'single' 位置:
=LOOKUPVALUE(
'MyLocation'[Location Name],
'MyLocation'[LocationKey],
'Location'[LocationKey]
)
它在 LocationKey 上匹配,但对于已通过 RLS 删除的记录,应该没有匹配项。
然而,当我测试最后一列时,RLS 被忽略,所有位置都通过。
我可以在 Power BI 中看到 table 就在我面前:
MyLocation 看起来像这样: (已应用 RLS)
Location
==========================
Location 3 Location 3
位置 看起来像这样: (未应用 RLS,但为什么其他位置不为空?)
Location LookupValue
==========================
Location 1 Location 1
Location 2 Location 2
Location 3 Location 3
Location 4 Location 4
Location 5 Location 5
...........
....
我希望 位置 看起来像这样:
Location LookupValue
==========================
Location 1 blank
Location 2 blank
Location 3 Location 3
Location 4 blank
Location 5 blank
...........
....
所以看来不管你用什么技巧,你真的不能连续使用 USERPRINCIPALNAME()。
我也试过将 USERPRINCIPALNAME()
定义为一个度量并使用它,但也失败了(现在不记得错误了,但我也会重试)
我也尝试过使用 'standalone parameter' table 来打开和关闭 RLS,使用 SELECTEDVALUE
但是参数 table 中的过滤值从未出现。 ISFILTERED
总是 returns false 尽管 table 被过滤了。
到目前为止这对我有用:
objective 是让给定用户自动看到他们自己的位置,但可以选择查看其他位置。
我尝试了很多东西,但最终我只是根据 table 这一事实创建了单独的措施,直接引用 USERPRINCIPALNAME
即这显示了相对于用户位置的位置总单位,相对于其他所有单位显示为零。
My Location Units:=
CALCULATE(
SUM([Units]),
FILTER(
'Location',
'Location'[LocationKey]=
LOOKUPVALUE(
'Employee'[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME()
)
)
)
然后我想:我不能只在维度上使用它吗?
Is My Location:=
CALCULATE(
IF(ISBLANK(MAX('Location'[LocationKey])),"No","Yes"),
FILTER(
'Location',
'Location'[LocationKey]=
LOOKUPVALUE(
'Employee'[LocationKey],
'Employee'[UserPrincipalName],
USERPRINCIPALNAME()
)
)
)
虽然我需要在行级别使用它,但它似乎可以工作,即使它是一个度量。
它使用CALCULATE(<expression>,FILTER(<table>,<expression>))
FILTER
部分做用户级过滤
表达式部分将其变为YES/NO
我可以使用它在 Power BI 中进行过滤,如果需要,我可以只选择当前用户的位置。
我怀疑所有这些表达式都不能写得更简单。不吝赐教
我仍然不知道为什么 LOOKUPVALUE
不遵守 RLS。我想知道是否可以,但我做错了什么,或者是否没有。
我明白你的意思了。 LOOKUPVALUE
似乎可以绕过 RLS 未经过滤地访问您的 table。我建议将此作为错误报告给 Microsoft。
在你的报告中,我建议使用这种形式的措施:
Measure =
VAR EmployeeLocation =
LOOKUPVALUE(Employee[LocationKey],
Employee[UserPrincipalName],
USERPRINCIPALNAME())
RETURN IF(ISFILTERED(Location[Location]),
<expression>,
CALCULATE(<expression>,
FILTER(Location, Location[LocationKey] = EmployeeLocation)))
这样,当 Location
未过滤时,它应该默认计算 EmployeeLocation
的值,否则将正常运行。
据我了解,Lookup[LookupValue] 是一个列(不是度量),使用您的第三个代码片段:“=LOOKUPVALUE( ...”
当您刷新模型时,计算列的结果就会具体化。它们不受在查询时应用的 RLS 的影响,就在计算度量之前。
这不是特定于 LOOKUPVALUE 函数。