SQL Server 表或者视图的行列安全和动态屏蔽

一.背景:

     经常碰到我们的客户朋友反馈:BI如何做到自主分析?SQL Server 有没有好的解决方案,这个时候我们一般上就会想到使用PowerBI 进行。但紧接着就会面临一下几个问题:

1.PowerBI 的数据源从哪里来?数据源又怎么控制到行列权限,确保数据的安全。

2.自主分析:我们需要结合线下的数据,如何做到自主。

    针对第一个问题,或许有很多朋友会将:我们的方案是通过PowerBI 连接表格模型(Tableuar)在表格模型上进行行列权限的控制。站在BI方案的角度,这的确是一个比较好的解决方案和思路。但紧接着就会引出第二个问题表格模型无法解决。

    PowerBI 在连接表格模型之后:

1.如果用的是导入模式,需要导入很多表,表之间的关系也需要梳理清楚,导入的数据量也是偏大;

2.如果用的是直连模式,那简直是一点自主都谈不上了。假如我需要引入一个新的数据源:不行。假如我需要更改一些计算逻辑:不行。假如我需要增加一个计算列:不行。以上这些操作统统都需要IT 技术人员来帮你完成。

    于是,我们在探寻一种新的方式来解决用户的困扰,众所周知;宽表用来一时爽;应运而生的,我们在数仓中抽象出一层为业务部门提供数据服务的层次(DWS);这样整个BI的架构往往会调整为:

    用户通过PowerBI 访问DWS 层的宽表视图获取数据,然后结合自己的业务和线下数据做自主分析。我们技术人员帮助业务部门提供准确标准DWS 层数据服务。

     那么有关表或者视图级的行列安全问题应运而生;接下来,我么一起探讨通过一些技术手段和方案来实现相关的行列安全限制;

二.技术手段:

  1. SQL Server 行级安全(RLS)

 

    作为SQL Server 2016的新特性,RLS 技术为我们提供了解决表或者索引视图的行级安全的可能,行级安全的设置在SQL Server中主要通过三步完成:

1>.创建谓词函数:

    首先需要明白什么是谓词:举个例子:猫是动物,3大于2。其中是,大于我们可以理解为谓词;他是连接两个客体之间关系的词。

    那么明白了谓词,我们就比较容易理解什么是谓词函数:定义表中某一行数据满足用户权限之间关系的函数,即为谓词函数。

    接下来,我们定义谓词函数。在微软的官方文档中,强烈建议我们单独建立相关的Schema(我们一般建议名字为:Security)。在该Schema下创建谓词函数。

CREATE FUNCTION Security.tvf_securitypredicateByRole(@TableViewName nvarchar(500),@ColumnName nvarchar(500) ,  @FilterValue AS nvarchar(50))  

    RETURNS  table   

WITH SCHEMABINDING  

AS 

RETURN (

 SELECT 1 AS RESULT

FROM Security.UserSecurity U

join Security.UserRole C ON U.RoleName=C.RoleName

where

C.UserName=USER_NAME() AND

  ISNULL(U.ColumnName,'')=CASE WHEN ISNULL(U.ColumnName,'')='' THEN  ISNULL(U.ColumnName,'') ELSE  @ColumnName END

AND   ISNULL(U.FilterValue,'')=CASE WHEN ISNULL(U.FilterValue,'')='' THEN  ISNULL(U.FilterValue,'') ELSE  @FilterValue END --缺省值为所有

AND ISNULL(U.TableViewName,'')=CASE WHEN ISNULL(U.TableViewName,'')='' THEN ISNULL(U.TableViewName,'') ELSE  @TableViewName END

)

    如上代码段,是一个谓词函数的定义的举例:通过以上一个例子:我们发现其实谓词函数本质是上一个表值函数,在该函数中,我们通过定义表名称,表列名,列字段的方式,实现将表和我们的权限控制表(Security.UserSecurity表,这张表可以定义要控制的表的列,过滤条件等。如下图:)之间建立起连接关系。通过函数传递相关信息,在函数中和权限表进行比对,有权限则返回true,否则返回false。

字段

类型

描述

ID

INT

主键

UserName

nvarchar(50)

用户名

TableViewName

nvarchar(500)

表或者视图名称

ColumnName

nvarchar(500)

需要控制的过滤的列名

FilterValue

nvarchar(4000)

过滤值

RoleName

nvarchar(500)

角色名称

 

2>创建安全策略:

    以上函数定义完成之后,那么怎么让表去调用呢?SQL Server 提供了Security Policy (安全策略)的设置。

CREATE SECURITY POLICY FactFinanceFilter 

ADD FILTER PREDICATE Security.tvf_securitypredicate('FactFinance','DepartmentGroupKey',DepartmentGroupKey)

ON [dbo].[FactFinance]

WITH (STATE = ON);  

GO

    通过以上脚本,既可以为表FactFinance 表开通有关DepartmentGroupKey 相关字段的行级过滤权限。

3>开通权限

通过以上两步已经完成了行级安全的设置,接下来,我们就需要对表和函数开通相关访问权限即可,完成相关测试工作。

4>注意事项:

  • 如果使用视图,必须使用索引视图(视图创建脚本前必须加上 WITH SCHEMABINDING  )。
  • 可以在安全策略的表或者上创建视图,但最好不要创建索引视图,索引视图会绕过安全策略。

2.SQL Server 列权限控制

 

    SQL Server的列级权限控制,设置起来相对简单;并且也不存在版本限制,我们只需要在用户或者数据库角色配置表或者视图的访问权限时,勾选访问列即可,如下图。

    虽然列级权限配置简单,但是需要我们注意的是,用起来就相对麻烦了:必须指定列名访问;也就是说Select * 的写法因为权限问题将永远无法返回数据,更为可惜的是我们用Excel或者PowerBI 连接表或者视图更加困难;如下图:

当然也可以通过高级模式,指定列名访问,不过这个大大增加了业务部门的使用难度。如下图:

    综上所述,行级安全和列级安全,尽管SQL Server 都有一些技术方案用来解决,但是我们在真正实施落地的时候还是需要综合考虑提出适合大家的相关技术方案。

3.SQL Server 动态数据屏蔽

动态数据掩码 (DDM) 通过对非特权用户屏蔽敏感数据来限制敏感数据的公开。 它可以用于显著简化应用程序中安全性的设计和编码。

掩码函数:

掩码使用到列上:

-- table with masked columns

CREATE TABLE Data.Membership

(

 MemberID int IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,

FirstName varchar(100) MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 1)') NULL,

 LastName varchar(100) NOT NULL, Phone varchar(12) MASKED WITH (FUNCTION = 'default()') NULL,

Email varchar(100) MASKED WITH (FUNCTION = 'email()') NOT NULL,

DiscountCode smallint MASKED WITH (FUNCTION = 'random(1, 100)') NULL

 );

插入数据,并授权用户访问:

GRANT UNMASK TO MaskingTestUser;

如下图:实现了动态屏蔽。

如果需要查看未经屏蔽的数据,则通过以下语句实现授权。

GRANT UNMASK TO MaskingTestUser;

 

  三.推荐方案:

  

如上图:

1.我们通过在DW中创建Security 的架构:在该架构下我们创建相关的谓词函数和用户权限控制表。同时我们创建权限索引视图;该视图使用上文讲到到行级安全和列级安全权限控制。

3.我们在DW中创建DWS的架构;该Schema下的所有视图最终都将为用户提供访问需求。在该层的视图,我们通过访问Security下的权限视图,并完成逻辑编写,形成宽表视图给到终端用户访问。(这里分为两类视图,一类是包含所有列的Owner视图,一类是根据不同的列权限开发的用户视图)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server中,视图(View)和(Table)是数据库中的两种不同类型的对象,它们有一些明显的区别。 首先,数据库中存储数据的基本单位,它由一些列和行组成,每列定义了数据的类型和属性,每行示一个实体。中的数据可以通过SQL操作语句进行增删改查。 而视图是虚拟,它是根据一个或多个查询语句定义的,它不存储数据,只提供了一种关于数据的逻辑视图。通过查询视图,可以将多个中的数据整合起来,方便用户进行查询和分析。视图本身可以像一样使用,可以用于数据读取、过滤和连接等操作。 其次,是实际存储数据的物理结构,数据的插入、更新和删除操作会直接影响本身,而视图只是查询语句的封装,对视图进行的操作实际上是对底层的操作。 此外,视图还具有以下特点: 1. 视图可以隐藏底层的细节,保护数据安全性。用户只能访问视图中允许显示的数据列,而不能直接访问底层。 2. 视图可以简化复杂的查询操作,通过提前对多个进行关联和筛选,减少了用户编写复杂查询语句的工作量。 3. 视图可以提供数据的逻辑展示,通过在视图中定义计算字段和筛选条件,可以生成更有用的数据展示形式。 总的来说,是实际存储数据的对象,而视图是对数据的逻辑示。视图可以整合数据、简化查询和保护数据,是SQL Server中非常常用和重要的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值