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来表示用户可以访问。
安全谓词
安全谓词就是将谓词函数绑定到表里面,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))GOINSERT INTO Person (PersonName, Department, Salary, User_Access)SELECT 'Ankit', 'CS', 40000, 'User_CS'UNION ALLSELECT 'Sachin', 'EC', 20000, 'User_EC'UNION ALLSELECT 'Kapil', 'CS', 30000, 'User_CS'UNION ALLSELECT 'Ishant', 'IT', 50000, 'User_IT'UNION ALLSELECT 'Aditya', 'EC', 45000, 'User_EC'UNION ALLSELECT 'Sunny', 'IT', 60000, 'User_IT'UNION ALLSELECT 'Rohit', 'CS', 55000, 'User_CS'GO
此时表已经被创建,并且插入了测试数据,执行下面语句检索有是有的记录:
SELECT * FROM Person
正如所示,目前有三个部门department(CS,EC,IT),并且User_Access列表示各自的用户组。让我们创建三个测试用户数据的账户语句如下:
--For CS departmentCREATE USER User_CS WITHOUT LOGIN--For EC departmentCREATE USER User_EC WITHOUT LOGIN-- For IT DepartmentCREATE USER User_IT WITHOUT LOGIN
在创建了用户组以后,授权读取权限给上面是哪个新建的用户,执行语句如下:
---授予select权限给所有的用户GRANT SELECT ON Person TO User_CSGRANT SELECT ON Person TO User_ECGRANT SELECT ON Person TO User_IT
现在我们创建一个谓词函数,该函数是对于查询用户是不可见的。
----Create functionCREATE FUNCTION dbo.PersonPredicate( @User_Access AS varchar(50) )RETURNS TABLEWITH SCHEMABINDINGASRETURN SELECT 1 AS AccessRightWHERE @User_Access = USER_NAME()GO
这个函数是只返回行,如果正在执行查询的用户的名字与User_Access 列匹配,那么用户允许访问指定的行。在创建该函数后,还需要创建一个安全策略,使用上面的谓词函数PersonPredicate来对表进行过滤逻辑的绑定,脚本如下:
--安全策略CREATE SECURITY POLICY PersonSecurityPolicyADD FILTER PREDICATE dbo.PersonPredicate(User_Access) ON dbo.PersonWITH (STATE = ON)
State(状态)为ON才能是策略生效,如果打算关闭策略,你可以改变状态为OFF。
再来看一下查询结果:
这次查询没有返回任何行,这意味着谓词函数的定义和策略的创建后,用户查询需要具有相应权限才能返回行,接下来使用不同用户来查询这个数据,首先,我们用用户User_CS来查询一下结果:
EXECUTE AS USER = 'User_CS'SELECT * FROM dbo.PersonREVERT
正如所示,我们看到只有三行数据数据该用户,User_CS,已经检索出来。因此,过滤函数将其他不属于该用户组的数据过滤了。
实际上这个查询执行的过程就是数据库内部调用谓词函数,如下所示:
SELECT * FROM dbo.Person
WHERE User_Name() = 'User_CS'
其他两组用户的查询结果是相似的这里就不一一演示了。
因此,我们能看到执行查询根据用的不同得到只属于指定用户组的指定数据。这就是我们要达成的目的。
到目前为止,我们已经演示了过滤谓词,接下来我们演示一下如何阻止谓词。执行如下语句来授权DML操作权限给用户。
--授权DML 权限GRANT INSERT, UPDATE, DELETE ON Dbo.Person TO User_CSGRANT INSERT, UPDATE, DELETE ON Dbo.Person TO User_ECGRANT 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.PersonREVERT
奇怪,新插入行并没有插入到该用户组'User_IT'中。而是出现在了'User_CS' 的用户组数据中。
--插入数据出现在了不同的用户组EXECUTE AS USER = 'User_CS'SELECT * FROM dbo.PersonREVERT
通过上面的例子我们发现,过滤谓词不不会阻止用户插入数据,因此没有错误,这是因为没有在安全策略中定义阻止谓词。让我们加入阻止谓词来显示报错,有四个阻止谓词AFTER INSERT, AFTER UPDATE, BEFORE UPDATE, 和 BEFORE DELETE可以使用。我们这里测试使用AFTER INSERT 谓词。这个谓词阻止用户插入记录到没有权限查看的数据用户组。
添加谓词阻止的安全策略,代码如下:
--添加阻止谓词ALTER SECURITY POLICY PersonSecurityPolicyADD 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操作被限制了。
注意:在例子中每个部门只有一个用户组成。如果在一个部门包含多个用户的情况下,我们需要创建分支登录为每个用户都分配需要的权限,因为谓词函数应用于用户基础并且安全策略取决于谓词函数。
行级别安全的限制
这里有几个行级别安全的限制:
- 谓词函数一定要带有WITH SCHEMABINDING关键词,如果函数没有该关键字则绑定安全策略时会抛出异常。
- 在实施了行级别安全的表上不能创建索引视图。
- 内存数据表不支持
- 全文索引不支持
总结
带有行级别安全功能的SQLServer2016,我们可以不通过应用程序级别的代码修改来实现数据记录的权限控制。行级别安全通过使用谓词函数和安全策略实现,不需要修改各种DML代码,伴随着现有代码即可实现。
SQL Server 2016 行级别权限控制相关推荐
- sql 如何设置行级锁_如何使用SQL Server 2016行级安全性过滤和阻止数据访问
sql 如何设置行级锁 SQL Server 2016 came with many new features and enhancements for existing ones, that con ...
- SQL Server 关于列的权限控制
SQL Server 关于列的权限控制 原文:SQL Server 关于列的权限控制 在SQL SERVER中列权限(Column Permissions)其实真没有什么好说的,但是好多人对这个都不甚 ...
- SQL Server使用视图做权限控制
问题引入 这天老鸟火急火燎的跑到菜鸟旁边,想必是遇到什么难题了:"现在有这么一个场景,假如有三种角色,并且存在层级关系,他们需要访问同一个数据源表,但是需要做权限控制,使得每种角色只能看到自 ...
- ssas表格模型 权限控制_如何在SQL Server 2016中自动执行SSAS表格模型处理
ssas表格模型 权限控制 There are many ways to process your SSAS Tabular Model. This can be achieved in SSIS u ...
- 【软件周刊】微软发布 Mac 版 Visual Studio,SQL Server 2016 SP1 紧跟节奏
2019独角兽企业重金招聘Python工程师标准>>> 上周有不少关于微软的新闻,而且隔三差五就弄个大新闻.先是宣布推出针对苹果 Mac 环境的 Visual Studio for ...
- sqlserver故障转移集群和alwayson的区别_详解SQL Server 2016 + AlwaysOn 无域集群
搭建 WSFC 配置计算机的 DNS 后缀 1.配置计算机的 DNS 后缀,注意在同个工作组 2.每个节点的机器都要做域名解析,修改 host 文件C:WindowsSystem32driverset ...
- SQL Server 2016 AlwaysOn 安装及配置介绍
SQL Server 2016 AlwaysOn 安装及配置介绍 Always On 可用性组功能是一个提供替代数据库镜像的企业级方案的高可用性和灾难恢复解决方案. SQL Server 2012 ...
- SQL Server 2016 SP1中的新功能和增强功能
SQL Server 2016 SP1 is released as announced by Microsoft. It comes with a bunch of new features and ...
- execution 排除_使用SQL Server 2016 Live Execution统计信息对SQL查询性能进行故障排除
execution 排除 SQL Server Management Studio a graphical interactive that allows you to interact with t ...
最新文章
- 发布|CES 2019 科技趋势(附40页PPT)
- linux 编译sqlitecpp,编译安装sqlite3数据库
- TADOStoredProc返回多个数据集
- 二 Java开发环境搭建
- 使用Python在Twitter上进行基本数据分析
- 富文本编辑器 CKeditor 配置使用
- 95-190-035-源码-window-Time Window 实现
- Java中的变量分类_Java十四天零基础入门-Java变量的作用域
- 剥开比原看代码03:比原是如何监听p2p端口的
- 5月第3周回顾:08软考举行 中国遭大范围SQL注入***
- 修改/etc/resolv.conf又恢复到原来的状态
- android 3dtouch插件,iOS-3DTouch的简单实现
- python绘制好几个子图_求助,python使用matplotlib画子图颜色,修改多个颜色报错...
- NI 视觉入门软件介绍
- 手机怎么修改浏览器的html,手机设置默认浏览器
- vue路由跳转总是跳转到首页,路由匹配不上
- html a href 文件下载 IE直接打开 内容乱码
- php jws 数据签名,JSON Web Signature 规范解析
- UML时序图(Sequence Diagram)
- _012_IDEA_idea 创建工作空间(空项目) 项目组
热门文章
- Android语言国际化values资源文件命名规则
- Eclipse使用Android2.3和3.0的SDK
- CentOS7,zabbix3.4通过,zabbix-Java-gateway监控Tomcat
- BZOJ2038: [2009国家集训队]小Z的袜子(hose)
- http接口服务方结合策略模式实现总结
- 【CMS】安装CMS
- Spring.NET 1.3.1 新特性探索系列2——WCF命名空间解析器
- Spring之旅—Spring模块介绍
- tcp3次握手,https加密,ca认证
- 【转载】python 编码问题 u'汉字'