通过在SSAS表格中使用动态行过滤器来动态屏蔽数据

问题描述

我正在尝试实现一种在SSAS表格导入上使用动态数据屏蔽的方法。默认情况下,据我所知,SQL Server Analysis Services 2016不支持此功能。我想我已经找到了一种使用动态行级安全性来实现此目的的方法。但是,我的结果与预期不符。

我的案例是一个Employee表。它包含大约2000行,我的测试用户被授权查看大约50行。 我已经导入了Employee表,添加了一个Security表(EmployeeKey,Username),并在Employee表上设置了行过滤器。与the sample from Microsoft大致相同。

此外,我还添加了一个名为EmployeeMask的表,该表包含相同的2000行,相同的EmployeeKeys和相同的列。但是,我已经“掩盖”了其余列的值。

使用模拟为我的测试用户的MDX查询,我从Employee表中检索了50名雇员,从EmployeeMask表中检索了2000名雇员。到现在为止还挺好。现在是我认为自己很聪明的部分。我重命名了Employee表EmployeeAuthorized并添加了一个计算表Employee,如下所示:

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

但是,对我的新计算表Employee使用MDX查询,我得到了所有2000行未屏蔽的信息。我的猜测是,已计算的表会事先得到处理,而我认为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),5),8);

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

INSERT INTO [dbo].[Security] VALUES
    (1,'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'),'masked');

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

pivot tables

解决方法

  1. Ditch UNION会忽略过滤器上下文和您的RLS。使用LOOKUPVALUE来确保用户有权访问EmployeeMasked上的行,具体取决于他们的EmployeeKey是否存在于EmployeeAuthorized

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

    返回的ADUsername值。
  3. 编辑您创建的角色,然后转到行过滤器标签。

  4. 查找EmployeeMask表

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

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

,

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

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

enter image description here

如您所见,关系如下:

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()

结果:

enter image description here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...