在 SSAS 表格中使用动态行筛选器进行动态数据屏蔽

Dynamic data masking by using a dynamic row filter in SSAS Tabular

我正在尝试实现一种在 SSAS 表格导入上使用动态数据屏蔽的方法。默认情况下,SQL Server Analysis Services 2016 不支持(据我所知)。我想我已经找到了一种使用动态行级别安全性来实现这一点的方法。然而,我的结果并不如预期。

我的案例是一名员工 table。它包含大约 2000 行,我的测试用户有权查看大约 50 行。 我导入了 Employee table,添加了 Security table (EmployeeKey, Username) 并在 Employee table 上设置了行过滤器。或多或少与 the sample from Microsoft.

相同

此外,我添加了一个名为 EmployeeMask 的 table,它包含相同的 2000 行,具有相同的 EmployeeKeys 和相同的列。但是,我有 'masked' 剩余列的值。

使用模拟我的测试用户的 MDX 查询,我从我的 Employee table 检索了 50 名员工,从我的 EmployeeMask table 检索了 2000 名员工。到目前为止,一切都很好。现在是我认为我聪明的部分。我重命名了我的 Employee table EmployeeAuthorized 并添加了一个计算的 table Employee 如下:

=UNION(
    EmployeeAuthorized; 
    FILTER(
        EmployeeMask; 
        LOOKUPVALUE(EmployeeAuthorized[EmployeeKey]; EmployeeAuthorized[EmployeeKey]; EmployeeMask[EmployeeKey]) 
            = BLANK()
    )
)

但是,对我新计算的 table 员工使用 MDX 查询,我得到了所有 2000 行的屏蔽。我的猜测是计算出的 table 会事先得到处理,而我认为 DAX 公式会根据请求执行。我的猜测对吗?有什么方法可以满足我的要求吗?

示例数据:

CREATE TABLE [dbo].[Employee] (--Renamed this to EmployeeAuthorized
    [EmployeeKey] INT NOT NULL,
    [EmployeeName] VARCHAR(50) NOT NULL
);

INSERT INTO [dbo].[Employee] VALUES
    (1, 'A A'), (2, 'B B'), (3, 'C C');

CREATE TABLE [dbo].[Fact] (
    [EmployeeKey] INT NOT NULL,
    [Value] INT NOT NULL
);

INSERT INTO [dbo].[Fact] VALUES
    (1, 1), (2, 2), (3, 5), (3, 8);

CREATE TABLE [dbo].[Security] (
    [EmployeeKey] INT NOT NULL,
    [UserName] VARCHAR(50) NOT NULL
);

INSERT INTO [dbo].[Security] VALUES
    (1, 'domain\u1'), (2, 'domain\u1'), (3, 'domain\u1'),
    (1, 'domain\u2');

如果需要:

CREATE TABLE [dbo].[EmployeeMask] (
    [EmployeeKey] INT NOT NULL,
    [EmployeeName] VARCHAR(50) NOT NULL
);

INSERT INTO [dbo].[EmployeeMask] VALUES
    (1, 'masked'), (2, 'masked'), (3, 'masked');

我正在尝试完成以下任务:

  1. 放弃 UNION 它会忽略过滤器上下文和您的 RLS。使用 LOOKUPVALUE 确保用户可以访问 EmployeeMasked 上的行,这取决于他们的 EmployeeKey 是否存在于 EmployeeAuthorized

  2. 编辑您的 EmployeeAuthorized table,使其包含一个 ADUsername 列。对于每个 EmployeeKey,存储将从 dax 函数返回的 ADUsername 值 USERNAME()

  3. 编辑您创建的角色并转到行过滤器选项卡。

  4. 找到 EmployeeMask table

  5. 添加以下 DAX 筛选器,如果角色 EmployeeKey/ADUsername 在 EmployeeAuthorizedy 中具有相应的查找授权记录,则角色强制属于该角色的用户只能看到 EmployeeMask 上的行。

      =EmployeeMask[EmployeeKey]
        =LOOKUPVALUE(
            EmployeeAuthorizedy[EmployeeKey],
            EmployeeAuthorized[EmployeeKey], EmployeeMask[EmployeeKey],
            EmployeeAuthorized[ADUsername], USERNAME()
        )

我能够解决这个难题如下:

我将 table 导入到我的 SSAS 表格模型中。我导入了 table Employee 两次,一次作为 Employee,一次作为 EmployeeKey,只有 EmployeeKey 列。

如您所见,关系如下:

Fact[EmployeeKey] *:1 (<< To Fact) EmployeeKey[EmployeeKey]
Employee[EmployeeKey] *:1 (<< To Both Tables >>) EmployeeKey[EmployeeKey]
Security[EmployeeKey] *:1 (<< To Security) Employee[EmployeeKey]

我添加了一个具有读取权限和以下行过滤器的角色:

Table Employee: =Employee[EmployeeKey]=LOOKUPVALUE(Security[EmployeeKey]; Security[UserName]; USERNAME(); Security[EmployeeKey]; Employee[EmployeeKey])
Table Security: =FALSE()

导致: