SQL Server 2016 行级别权限控制

原文:SQL Server 2016 行级别权限控制

背景

假如我们有关键数据存储在一个表里面,比如人员表中包含员工、部门和薪水信息。只允许用户访问各自部门的信息,但是不能访问其他部门。一般我们都是在程序端实现这个功能,而在sqlserver2016以后也可以直接在数据库端实现这个功能。

解决

安全已经是一个数据方面的核心问题,每一代的MS数据库都有关于安全方面的新功能,那么在Sql Server 2016,也有很多这方面的升级,比如‘Row Level Security’, ‘Always Encrypted’, ‘Dynamic Data Masking’, 和‘Enhancement of Transparent Data Encryption’ 等等都会起到安全方面的作用。本篇我将介绍关于Row Level Security (RLS--行级别安全), 能够控制表中行的访问权限。RLS 能使我们根据执行查询人的属性来控制基础数据,从而帮助我们容易地为不同用户提透明的访问数据。行级安全性使客户能够根据执行查询的用户的特性控制数据库中的行。

为了实现RLS我们需要准备下面三个方面:

  1. 谓词函数
  2. 安全谓词
  3. 安全策略

逐一描述上面三个方面

谓词函数

谓词函数是一个内置的表值函数,用于检查用户执行的查询访问数据是否基于其逻辑定义。这个函数返回一个1来表示用户可以访问。

安全谓词

安全谓词就是将谓词函数绑定到表里面,RLS提供了两种安全谓词:过滤谓词和阻止谓词。过滤谓词就是在使用SELECT, UPDATE, 和 DELETE语句查询数据时只是过滤数据但是不会报错。而阻止谓词就是在使用违反谓词逻辑的数据时,显示地报错并且阻止用户使用 AFTER INSERT, AFTER UPDATE, BEFORE UPDATE, BEFORE DELETE 等操作。

安全策略

安全策略对象专门为行级别安全创建,分组所有涉及谓词函数的安全谓词。

实例

实例中我们创建一个Person表和测试数据,最后我们让不懂得用户访问各自部门的信息,代码如下:

Create table dbo.Person

(

PersonId INT IDENTITY(1,1),

PersonName varchar(100),

Department varchar(100),

Salary INT,

User_Access varchar(50)

)

GO

INSERT INTO Person (PersonName, Department, Salary, User_Access)

SELECT ‘Ankit‘, ‘CS‘, 40000, ‘User_CS‘

UNION ALL

SELECT ‘Sachin‘, ‘EC‘, 20000, ‘User_EC‘

UNION ALL

SELECT ‘Kapil‘, ‘CS‘, 30000, ‘User_CS‘

UNION ALL

SELECT ‘Ishant‘, ‘IT‘, 50000, ‘User_IT‘

UNION ALL

SELECT ‘Aditya‘, ‘EC‘, 45000, ‘User_EC‘

UNION ALL

SELECT ‘Sunny‘, ‘IT‘, 60000, ‘User_IT‘

UNION ALL

SELECT ‘Rohit‘, ‘CS‘, 55000, ‘User_CS‘

GO

此时表已经被创建,并且插入了测试数据,执行下面语句检索有是有的记录:

SELECT * FROM Person

正如所示,目前有三个部门department(CS,EC,IT),并且User_Access列表示各自的用户组。让我们创建三个测试用户数据的账户语句如下:

--For CS department

CREATE USER User_CS WITHOUT LOGIN

--For EC department

CREATE USER User_EC WITHOUT LOGIN

-- For IT Department

CREATE USER User_IT WITHOUT LOGIN

在创建了用户组以后,授权读取权限给上面是哪个新建的用户,执行语句如下:

---授予select权限给所有的用户

GRANT SELECT ON Person TO User_CS

GRANT SELECT ON Person TO User_EC

GRANT SELECT ON Person TO User_IT

现在我们创建一个谓词函数,该函数是对于查询用户是不可见的。

----Create function

CREATE FUNCTION dbo.PersonPredicate

( @User_Access AS varchar(50) )

RETURNS TABLE

WITH SCHEMABINDING

AS

RETURN SELECT 1 AS AccessRight

WHERE @User_Access = USER_NAME()

GO

这个函数是只返回行,如果正在执行查询的用户的名字与User_Access 列匹配,那么用户允许访问指定的行。在创建该函数后,还需要创建一个安全策略,使用上面的谓词函数PersonPredicate来对表进行过滤逻辑的绑定,脚本如下:

--安全策略

CREATE SECURITY POLICY PersonSecurityPolicy

ADD FILTER PREDICATE dbo.PersonPredicate(User_Access) ON dbo.Person

WITH (STATE = ON)

State(状态)为ON才能是策略生效,如果打算关闭策略,你可以改变状态为OFF。

再来看一下查询结果:

这次查询没有返回任何行,这意味着谓词函数的定义和策略的创建后,用户查询需要具有相应权限才能返回行,接下来使用不同用户来查询这个数据,首先,我们用用户User_CS来查询一下结果:

EXECUTE AS USER = ‘User_CS‘

SELECT * FROM dbo.Person

REVERT

正如所示,我们看到只有三行数据数据该用户,User_CS,已经检索出来。因此,过滤函数将其他不属于该用户组的数据过滤了。

实际上这个查询执行的过程就是数据库内部调用谓词函数,如下所示:

SELECT * FROM dbo.Person

WHERE User_Name() = ‘User_CS‘

其他两组用户的查询结果是相似的这里就不一一演示了。

因此,我们能看到执行查询根据用的不同得到只属于指定用户组的指定数据。这就是我们要达成的目的。

到目前为止,我们已经演示了过滤谓词,接下来我们演示一下如何阻止谓词。执行如下语句来授权DML操作权限给用户。

--授权DML 权限

GRANT INSERT, UPDATE, DELETE ON Dbo.Person TO User_CS

GRANT INSERT, UPDATE, DELETE ON Dbo.Person TO User_EC

GRANT INSERT, UPDATE, DELETE ON Dbo.Person TO User_IT

我们用用户User_IT执行插入语句,并且插入用户组为UserCS的,语句如下:

EXECUTE AS USER = ‘User_IT‘

INSERT INTO Person (PersonName, Department, Salary, User_Access)

SELECT ‘Soniya‘, ‘CS‘, 35000, ‘User_CS‘

REVERT

but,竟然没有报错,插入成功了。

让我们在检查一下用户数据插入的情况:

EXECUTE AS USER = ‘User_IT‘

SELECT * FROM dbo.Person

REVERT

奇怪,新插入行并没有插入到该用户组‘User_IT‘中。而是出现在了‘User_CS‘ 的用户组数据中。

--插入数据出现在了不同的用户组

EXECUTE AS USER = ‘User_CS‘

SELECT * FROM dbo.Person

REVERT

通过上面的例子我们发现,过滤谓词不不会阻止用户插入数据,因此没有错误,这是因为没有在安全策略中定义阻止谓词。让我们加入阻止谓词来显示报错,有四个阻止谓词AFTER INSERT, AFTER UPDATE, BEFORE UPDATE, 和 BEFORE DELETE可以使用。我们这里测试使用AFTER INSERT 谓词。这个谓词阻止用户插入记录到没有权限查看的数据用户组。

添加谓词阻止的安全策略,代码如下:

--添加阻止谓词

ALTER SECURITY POLICY PersonSecurityPolicy

ADD BLOCK PREDICATE dbo.PersonPredicate(User_Access)

ON dbo.Person AFTER INSERT

现在我们用之前类似代码再试一下,是否可以插入数据:

EXECUTE AS USER = ‘User_CS‘

INSERT INTO Person (PersonName, Department, Salary, User_Access)

SELECT ‘Sumit‘, ‘IT‘, 35000, ‘User_IT‘

REVERT

 

擦,果然这次错误出提示出现了,阻止了不同权限用户的插入。因此我们能说通过添加阻止谓词,未授权用户的DML操作被限制了。

注意:在例子中每个部门只有一个用户组成。如果在一个部门包含多个用户的情况下,我们需要创建分支登录为每个用户都分配需要的权限,因为谓词函数应用于用户基础并且安全策略取决于谓词函数。

 

行级别安全的限制

这里有几个行级别安全的限制:

  1. 谓词函数一定要带有WITH SCHEMABINDING关键词,如果函数没有该关键字则绑定安全策略时会抛出异常。
  2. 在实施了行级别安全的表上不能创建索引视图。
  3. 内存数据表不支持
  4. 全文索引不支持

总结

带有行级别安全功能的SQLServer2016,我们可以不通过应用程序级别的代码修改来实现数据记录的权限控制。行级别安全通过使用谓词函数和安全策略实现,不需要修改各种DML代码,伴随着现有代码即可实现。

原文地址:https://www.cnblogs.com/lonelyxmas/p/8196630.html

时间: 2024-10-10 07:26:12

SQL Server 2016 行级别权限控制的相关文章

Sql Server数据库对象访问权限控制

以下内容主要针对database层面的数据访问权限(比如select, insert, update, delete, execute…) 1.直接给user权限GRANT EXECUTE TO [user] 2.通过role 控制权限,把user加入role中,继承Role所拥有的权限GRANT EXECUTE TO [Role]ALTER ROLE [Role] ADD MEMBER [Member] 3.通过app role的方式访问数据库Application Role 是数据库级别的R

Sql Server 2016中增加了对JSON的内置支持

原文地址:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/built-in-json-support-in-sql-server-2016/ 在数据库层对JSON提供支持,是请求排名最靠前的特性之一,在Microsoft Connect网站上对他的投票量超过了1000.微软承诺,在Sql Server 2016版本中,会提供内置的JSON支持.注意这并不是Sql Server 2005已有特性XML原生支持的翻版.微软的目标是创

SQL Server 2016 + AlwaysOn 无域集群

原文:SQL Server 2016 + AlwaysOn 无域集群 目录 AlwaysOn 搭建 WSFC 配置 AlwaysOn 可读副本的负载均衡 使用故障转移 [========] AlwaysOn AlwaysOn 可用性组概述 (SQL Server) 搭建 WSFC 配置计算机的 DNS 后缀 配置计算机的 DNS 后缀,注意在同个工作组 每个节点的机器都要做域名解析,修改 host 文件C:\Windows\System32\drivers\etc 安装故障转移集群 节点服务器添

SQL Server 2016 AlwaysOn 安装及配置介绍

SQL Server 2016  AlwaysOn 安装及配置介绍 Always On 可用性组功能是一个提供替代数据库镜像的企业级方案的高可用性和灾难恢复解决方案. SQL Server 2012 中引入了 Always On 可用性组功能,此功能可最大程度地提高一组用户数据库对企业的可用性. "可用性组" 针对一组离散的用户数据库(称为"可用性数据库" ,它们共同实现故障转移)支持故障转移环境. 一个可用性组支持一组读写主数据库以及一至八组对应的辅助数据库. (

SQL Server 事务隔离级别详解

原文:SQL Server 事务隔离级别详解 标签: SQL SEERVER/MSSQL SERVER/SQL/事务隔离级别选项/设计数据库事务级别 SQL 事务隔离级别 概述 隔离级别用于决定如果控制并发用户如何读写数据的操作,同时对性能也有一定的影响作用. 步骤 事务隔离级别通过影响读操作来间接地影响写操作:可以在回话级别上设置事务隔离级别也可以在查询(表级别)级别上设置事务隔离级别.事务隔离级别总共有6个隔离级别:READ UNCOMMITTED(未提交读,读脏),相当于(NOLOCK)R

SQL Server 2016五大优势挖掘企业用户数据价值

转载自:http://soft.zdnet.com.cn/software_zone/2016/0318/3074442.shtml 3月10日,微软公司在美国纽约举办了一场名为“Data Driven”的活动,正式发布了新一代SQL Server 2016, 与此同时,还附赠了两条爆炸性消息:微软将SQL Server 2016开放给linux,同时还发布了一款针对Oracle数据库的迁移工具,以及相关的迁移优惠政策. 业内对这两条消息进行了各种各样的猜想和推测. 一周后,SQL Server

[译]SQL Server分析服务的权限配置

简介: 本文介绍如何配置SSAS数据库和cube相关维度的安全设置. 相对数据引擎来说,在Management Studio中配置分析服务的安全设置基本没什么区别.但是也会有一些限制,比如SSAS的权限配置都是围绕角色进行的,其次,角色的成员必须是基于windows或者ad环境的,SQL Server用户(比如sa)是无法使用的.还有,权限是无法直接授予给windows或者ad用户或者组的,这些用户或者组必须填加到角色中才可以.另外,如果UAC处于打开的状态,那么比如要以"Run as Admi

SQL Server分析服务的权限配置

 简介: 本文介绍如何配置SSAS数据库和cube相关维度的安全设置. 相对数据引擎来说,在Management Studio中配置分析服务的安全设置基本没什么区别.但是也会有一些限制,比如SSAS的权限配置都是围绕角色进行的,其次,角色的成员必须是基于windows或者ad环境的,SQL Server用户(比如sa)是无法使用的.还有,权限是无法直接授予给windows或者ad用户或者组的,这些用户或者组必须填加到角色中才可以.另外,如果UAC处于打开的状态,那么比如要以"Run as A

SQL Server 2016的数据库范围内的配置

SQL Server 2016真的让人眼前一亮.几天前微软就提供了RCO(候选发布版)版本的下载.我已经围观了一圈RCO版本,其中一个最拽的功能是数据库范围内的配置(Database Scoped Configuration),在今天的文章里我想谈谈它.补充几句:装好之后,居然发现没有SSMS,崩溃中,原来是在向导中就有独立的安装程序,好吧! 这配色,真是低调有内涵. 另外,如过你的电脑已经安装了就[Microsoft Visual Studio 2010 Shell(独立)Redistribu