本篇文章是SQL Server安全系列的第四篇,详细内容请参考原文


权限授予主体访问对象,以执行某些操作。SQL Server有大量你可以授予给主体的权限,你甚至可以拒绝或回收权限。这听起来有点复杂,但在这一系列,你将知道SQL Server权限是如何工作的,你可以非常精细地在数据库和服务器对象上控制对象创建、数据访问、以及其他类型操作。
权限
权限像一个签证允许你访问外国,通常有一些基本条件。比如,你只有六个月的期限,你被限制在3/7的地区旅行。类似的,SQL Server权限给主体访问数据库对象做一些事或执行操作。权限可以允许主体读取表的数据或表的某一部分,或能够运行一段特定的代码。甚至允许主体给其他登录名授予权限。你可以给不同的主体授予数百种不同的权限。
在授予权限时,你要遵循最小特权原则。最小特权意味着,你给一个主体需要完成一个任务的权限——没有多也没有少。坚持最小特权原则,是数据库安全的重要步骤。如果主体在数据库中唯一能做的事情是读取产品信息,这个主体就不应该能有意或无意删除表中的内容。本质上是建立一个严密的容器限制主体可以做什么。
权限类型
SQL Server有许多种你可以授予主体控制访问安全对象的权限。下面列出最常见的权限:
控制:赋予安全对象的所有可能的权限,使主体成为安全对象的虚拟拥有者。这包括将安全对象授予权限给其他主体。
创建:赋予创建一个特定对象的能力,这取决于它被授予的范围。例如,CREATE DATABASE权限允许主体在SQL Server实例创建新的数据库。
更改:赋予更改安全对象属性的权限,除了更改所有者。这个权限包含了同范围的alter、create、drop对象的权限(比如,用户对表A有更改权限,那么它能够add/alter/drop列、create/drop索引约束等)例如,一个数据库级别的更改权限,包括更改表和架构权限。
删除:允许一个主体删除任何或所有存储在表中的数据。是一个非常危险的权限!
模拟<登录>或者模拟<用户名>:赋予主体模拟另一个登录/用户。通常用于改变存储过程的执行上下文。
插入:允许主体往表中插入新记录
选择:授予主体从一个特定的表读取数据。这是用户需要的最常见的权限,以便他们可以在表上执行查询。
接管所有权:Confers on a principal permission to take ownership of an object. Granting this permission does not immediately transfer ownership. Instead, it allows the principal to take ownership at some future time.
更新:允许主体更新表中的数据。
查看定义:赋予主体权限查看安全对象的定义。这是一个重要的权限,因为结构信息在数据库攻击中是非常有用的。如果没有这个权限,攻击者发现数据库或服务器实例有价值目标的能力将严重受限。
创建和更改权限可以使用ANY关键字:CREATE ANY <object type> and ALTER ANY <object type>.这些权限授予创建或更改任何指定类型安全对象。例如,在数据库级别上授予ALTER ANY SCHEMA,允许改变数据库中任何架构的属性。在服务器级别上,ALTER ANY LOGIN允许主体改变服务器上任何登录名。使用ANY关键字,可以灵活的让主体创建或修改一整类的对象,而不是一个单一的对象。只是要注意,在创建和修改权限之间有一些细微的差别。
当你考虑在SQL Server安全对象的数量和一个对象可以拥有潜在权限类型的数量时,你开始意识到有颗粒的权限。你可以应用最小特权原则来实现任何用户或角色的权限集,通过给予用户恰当的权限来完成一项任务,而不需要将其他对象暴露。
提示:如果你使用SQL Server早期版本,你会意识到,SQL Server 2005及之后版本完全修改了可用的权限。你不必再将一个用户分配给一个可能有几十个不必要的权限的角色,从而违反了最小特权,并将数据库暴露在有意或偶然的滥用。
这里一个主要考虑是,授予一个权限不一定有效地授予执行一项操作的能力。有时还需要其他权限,提供一个全面的安全上下文来执行敏感操作的能力。一个很常见的例子是创建表权限。授予这个权限,理论上允许一个主体在特定的数据库下创建表。但主体还需要有能力在一个架构中创建表。如果主体没有对任何架构的更改权限,它将无法创建一个表。
权限语句
即使你是通过图形化工具分配权限,底层还是执行TSQL权限语句。
GRANT:授予对安全对象或操作的权限给主体
REVOKE:“Un-grant”权限,取消一个早期做的grant语句。撤销的权限仍然可以通过在具有权限的组或角色中继承。当你创建新的对象时,revoke是默认的权限状态,所以特定权限没有授予,但是可以继承。
DENY:拒绝撤销权限,使它不能被继承。这是最具限制性的权限,并且优先于所有其他权限。DENY不适用于sysadmin角色的成员或对象的所有者。
不要低估DENY权限的重要性。例如,假设你有一个临时雇员,他是进来做数据输入,你不希望他能够编辑或删除现有记录。你已经分配给editor角色(公司内部人员都属于)对某些表的足够的权限。你可以创建一个特殊的登录名,然后在适当的表上deny UPDATE和DELETE权限。临时雇员可以从editor角色继承足够的权限输入新记录,但是不能修改/删除已存在的记录。
授予权限
在Management Studio下授予权限的最灵活的方法是修改数据库用户或角色的属性。你还可以通过修改单个对象的属性来授予权限,但这种方法不灵活,并且具有更高的维护成本。
下面的练习将在AdventureWorks2012数据库创建自定义数据库角色。这个角色的成员,需要必要的权限插入和更新一些HR相关的表,并且能够执行相关的存储过程,但没有其他的特殊权限。
提示:一旦你为一个用户配置权限,然后需要为另一个用户重复上述过程,授予和第一个用户同样的权限,那么把权限分配给一个角色,然后简单地将用户添加到角色即可。
你可以利用第二篇在AdventureWorks2012数据库下创建的用户Topaz。如果你没有创建用户,执行代码4.1创建登录名和用户。

USE master;
GO
CREATE LOGIN Topaz WITH PASSWORD = 'yBqyZIPT8}b]b[{5al0v';
GO
USE AdventureWorks2012;
GO
CREATE USER Topaz FOR LOGIN Topaz
WITH DEFAULT_SCHEMA = HumanResources;
GO

代码4.1 创建创建名并映射到数据库用户
在AdventureWorks2012数据库创建一个DataEntry自定义数据库角色,参考如下步骤:
1、SSMS连接到安装有AdventureWorks2012数据库的实例。对象资源管理器->数据库->AdventureWorks2012->安全性->角色->数据库角色
2、右击数据库角色,弹出菜单选择新建数据库角色
3、角色名称键入DataEntry,所有者dbo
4、点击添加按钮,将用户Topaz添加到角色(如果用户不存在请先创建)。在你关闭选择数据库用户或角色对话框后,数据库角色-新建对话框应该如图4.1所示

图4.1 创建DataEntry数据库角色并添加Topaz用户
5、点击确定保存修改并创建角色
当前DataEntry角色并不允许角色中的成员能做什么,因为你还没有给角色分配任何权限。DataEntry角色中的成员需要能够往表Employee、Address、JobCandidate插入和更新数据,同时他们需要执行uspUpdateEmployeeHireInfo和uspUpdateEmployeePersonaInfo存储过程。但是他们不能查看存储过程的定义。
使用下面的步骤给DataEntry角色添加合适的权限
1、对象资源管理器->数据库->AdventureWorks2012->安全性->角色->数据库角色->DataEntry
2、右击DataEntry,弹出菜单选择属性。打开数据库角色属性对话框
3、左侧选择安全对象,这个页面让你选择角色有权操作的安全对象,并指定对安全对象上的权限
4、点击“搜索”按钮添加安全对象。这将打开“添加对象”对话框,该对话框提供了特定对象、特定类型的所有对象、属于该架构的所有对象的选项。在本例中,因为你想为表和存储过程中添加权限,图4.2中保持默认选择-特定对象,然后单击“确定”

图4.2 选择添加对象
5、打开“选择对象”对话框。单击“对象类型”按钮打开“选择对象类型”对话框,然后从列表中选择“存储过程”和“表”,如图4.3所示。请单击“确定”以关闭该对话框并返回“选择对象”对话框,该对话框现在看起来像图4.4。你将看到在对象类型框中列出的存储过程和表

图4.3 选择对象类型

图4.4 选择对象
6、单击“浏览”按钮以查看数据库中的存储过程和表的列表。这将打开“查找对象”对话框,向下滚动查找并选择对象。

图4.5 选择存储过程和表
7、单击“确定”以关闭“查找对象”对话框中。此时你选择的对象以分号分隔列在选择对象对话框中,如图4.6所示。请单击“确定”以关闭该对话框并保存更改

图4.6 选择对象结果
8、现在DataEntry数据库角色属性对话框列出你选择的安全对象,并且列出每个对象可用的权限。DataEntry角色成员需要可以插入和更新数据到这些表,逐一选择表,在对话框的下部勾选插入/更新授予列的复选框。图4.7显示了HumanResources.Employee表的权限

图4.7 在表上授予插入/更新权限
提示:授予(Grant)允许指定的权限,具有授予权限(With Grant)允许用户或角色授予其他主体的权限。小心With Grant权限!
9、对于每一个存储过程,授予执行权限并拒绝查看定义权限。图4.8显示了useUpdateEmployeeHireInfo存储过程的权限

图4.8 授予执行过程权限、拒绝查看定义权限
10、在“数据库角色属性”对话框中单击“确定”以保存你的更改并提交到数据库。根据选定的对象和权限的数量,这可能需要一些时间。
当然,你可以使用T-SQL代码创建对象并分配权限。代码4.2创建DataEntry角色,添加Topaz用户,然后分配和图形界面相同的权限。

-- Create the DataEntry role and assign Topaz to it
CREATE ROLE [DataEntry] AUTHORIZATION [dbo];
ALTER ROLE [DataEntry] ADD MEMBER [Topaz];
-- Assign permissions to the DataEntry role
GRANT INSERT ON [HumanResources].[Employee] TO [DataEntry];
GRANT UPDATE ON [HumanResources].[Employee] TO [DataEntry];
GRANT INSERT ON [HumanResources].[JobCandidate] TO [DataEntry];
GRANT UPDATE ON [HumanResources].[JobCandidate] TO [DataEntry];
GRANT INSERT ON [Person].[Address] TO [DataEntry];
GRANT UPDATE ON [Person].[Address] TO [DataEntry];
GRANT EXECUTE ON [HumanResources].[uspUpdateEmployeeHireInfo] TO [DataEntry];
DENY VIEW DEFINITION ON [HumanResources].[uspUpdateEmployeeHireInfo] TO [DataEntry];
GRANT EXECUTE ON [HumanResources].[uspUpdateEmployeePersonalInfo] TO [DataEntry]
DENY VIEW DEFINITION ON [HumanResources].[uspUpdateEmployeePersonalInfo] TO [DataEntry];
GO

代码4.2 语句创建角色并分配权限
检查和测试权限
如果你想检查DataEntry角色的权限,你可以使用GUI工具或执行T-SQL代码访问数据库对象的元数据。使用GUI,对象资源管理器->数据库->AdventureWorks2012->安全性->角色->数据库角色->DataEntry->属性。这将打开和创建角色相同的"数据库角色属性"对话框,你可以使用安全对象审查该角色的权限。
或者你可以使用代码4.3中的T-SQL查看DataEntry角色的权限,利用sys.database_permissions和sys.database_principals安全目录视图和sys.objects目录视图。

SELECT DB_NAME() AS 'Database', p.name, p.type_desc, dbp.state_desc,
dbp.permission_name, so.name, so.type_desc
FROM sys.database_permissions dbp
LEFT JOIN sys.objects so ON dbp.major_id = so.object_id
LEFT JOIN sys.database_principals p ON dbp.grantee_principal_id = p.principal_id
WHERE p.name = 'DataEntry'
ORDER BY so.name, dbp.permission_name;

代码4.3 查看DataEntry角色的权限
当你执行上面代码,你将会看到结果如图4.9所示

图4.9 DataEntry角色的权限
你可以通过打开新建查询->更改连接用Topaz登录测试这些权限。然后尝试在HumanResources.Employee、HumanResources.JobCandidate、Person.Address表插入新行或更新已有数据,并执行分配权限的存储过程。这些操作应该成功。然后尝试插入或更新其他表中的数据,这些操作应该失败。你应该只能够执行已经授予的权限。
你可以用代码4.4执行相同的测试。代码开始设置的执行上下文为Topaz,DataEntry角色的成员。然后插入新行到Person.Address表。这一操作成功,因为角色允许在Person.Address表插入数据。然后代码试图插入新行到HumanResources.Department表,插入失败,因为角色在此表没有insert权限。接下来的代码成功执行HumanResources.uspUpdateEmployeePersonalInfo存储过程;执行dbo.uspGetManagerEmployees失败,因为角色没有此过程执行权限。最后,代码将执行上下文切回到登录时的安全上下文。

EXECUTE AS USER = 'Topaz';
-- Succeeds
INSERT INTO Person.Address
(AddressLine1, City, StateProvinceID, PostalCode)
VALUES
('8 Hazelnut', 'Irvine', 9, '');
GO
-- Fails
INSERT INTO HumanResources.Department
(Name, GroupName)
VALUES
('Advertising', 'Sales and Marketing');
GO
-- Succeeds (doesn't actually change any data)
DECLARE @RC INT;
EXECUTE @RC = HumanResources.uspUpdateEmployeePersonalInfo
1, '', '1963-03-02', 'S', 'M';
GO
-- Fails
EXECUTE dbo.uspGetManagerEmployees 1;
GO
REVERT;

代码4.4 测试DataEntry角色的权限
总结
The ability to assign granular permissions on securable objects throughout SQL Server to various types of principals gives you very fine control over the security of a SQL Server instance.它让你充分利用最小特权的安全原则,能够限制主体执行操作和访问数据的能力到他们需要的最低限度。

【译】第四篇 SQL Server安全权限的更多相关文章

  1. 第四篇 SQL Server安全权限

    本篇文章是SQL Server安全系列的第四篇,详细内容请参考原文. 权限授予主体访问对象,以执行某些操作.SQL Server有大量你可以授予给主体的权限,你甚至可以拒绝或回收权限.这听起来有点复杂 ...

  2. 【译】第九篇 SQL Server代理了解作业和安全

    本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这一系列的上一篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本 ...

  3. 【译】第四篇 SQL Server代理配置数据库邮件

    本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Serve ...

  4. 【译】第九篇 SQL Server安全透明数据加密

    本篇文章是SQL Server安全系列的第九篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  5. 【译】第一篇 SQL Server代理概述

    本篇文章是SQL Server代理系列的第一篇,详细内容请参考原文. SQL Server代理是SQL Server的作业调度和告警服务,如果使用得当,它可以大大简化DBA的工作量.SQL Serve ...

  6. 第四篇 SQL Server代理配置数据库邮件

    本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Serve ...

  7. 【译】第一篇 SQL Server安全概述

    本篇文章是SQL Server安全系列的第一篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...

  8. 【译】第二篇 SQL Server安全验证

    本篇文章是SQL Server安全系列的第二篇,详细内容请参考原文. 验证是检验主体的过程.主体需要唯一标识,那样SQL Server可以确定主体有哪些权限.正确的验证是提供安全访问数据库对象的必要的 ...

  9. 【译】第二篇 SQL Server代理作业步骤和子系统

    本篇文章是SQL Server代理系列的第二篇,详细内容请参考原文. SQL Server代理作业由一系列的一个或多个作业步骤组成.一个作业步骤分配给一个特定的作业子系统(确定作业步骤去完成的工作). ...

随机推荐

  1. 透彻掌握Promise的使用

    Promise的重要性我认为我没有必要多讲,概括起来说就是必须得掌握,而且还要掌握透彻.这篇文章的开头,主要跟大家分析一下,为什么会有Promise出现. 在实际的使用当中,有非常多的应用场景我们不能 ...

  2. 第三十二节,使用谷歌Object Detection API进行目标检测、训练新的模型(使用VOC 2012数据集)

    前面已经介绍了几种经典的目标检测算法,光学习理论不实践的效果并不大,这里我们使用谷歌的开源框架来实现目标检测.至于为什么不去自己实现呢?主要是因为自己实现比较麻烦,而且调参比较麻烦,我们直接利用别人的 ...

  3. 一个小误区 JS中的contains

    在Java语言中,contains可以用于判断str1是否包含str2 原生JS中是有contains方法的 但它并不是字符串方法,,仅用于判断DOM元素的包含关系,参数是Element类型 若要在J ...

  4. Failed to resolve: com.android.support:appcompat-v7:28 问题解决

    apply plugin: 'com.android.application' android { compileSdkVersion buildToolsVersion "28.0.2&q ...

  5. (贪心) nyoj1036-非洲小孩

    题目描述: 家住非洲的小孩,都很黑.为什么呢?第一,他们地处热带,太阳辐射严重.第二,他们不经常洗澡.(常年缺水,怎么洗澡.)现在,在一个非洲部落里,他们只有一个地方洗澡,并且,洗澡时间很短,瞬间有木 ...

  6. 关于 C# 中 Dictionary与Hashtable的性能测试

    https://www.cnblogs.com/qianxingdewoniu/p/5266243.html

  7. Qt ------ QFileDialog

    QString strFile = QFileDialog::getOpenFileName(this,QStringLiteral("选择Excel文件"),"&quo ...

  8. Hadoop ha CDH5.15.1-hadoop集群启动后,集群容量不正确,莫慌,这是正常的表现!

    Hadoop ha CDH5.15.1-hadoop集群启动后,集群容量不正确,莫慌,这是正常的表现! 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.集群启动顺序 1>. ...

  9. java io系列13之 BufferedOutputStream(缓冲输出流)的认知、源码和示例

    本章内容包括3个部分:BufferedOutputStream介绍,BufferedOutputStream源码,以及BufferedOutputStream使用示例. 转载请注明出处:http:// ...

  10. HDFS-JavaAPI

    一.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...