第四篇 SQL Server安全权限

本篇文章是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, ‘92602‘);
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, ‘295847284‘, ‘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.它让你充分利用最小特权的安全原则,能够限制主体执行操作和访问数据的能力到他们需要的最低限度。

时间: 2024-08-03 15:46:26

第四篇 SQL Server安全权限的相关文章

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

本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Server代理同样提供创建警报,能够以通知的形式将消息发送给设定的操作员.这些通知可以通过数据库邮件发送,数据库邮件是内置在SQL Server和SQL Server代理能够发送和接收电子邮件.在这一篇,你将学习如何配置数据库邮件发送和接收操作,以及一些基本的数据库邮件故障排除步骤.数据库邮件的简要概述在S

第五篇 SQL Server代理理解代理错误日志

本篇文章是SQL Server代理系列的第五篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.在第四篇中我们看到,SQL Server代理可以通过数据库邮件发送通知.如果有什么不正确的,你必须查看数据库邮件日志.在这一篇,你将学习如何理解和查看所有相关的SQL Server代理错误日志.你将回顾最常见的错误信息,掌握哪些信息需要你采取行动,哪些信息只是单纯的信息而已.一旦你理解错误日志,在处理SQL Serv

第十篇 SQL Server代理使用代理帐户

本篇文章是SQL Server代理系列的第十篇,详细内容请参考原文 在这系列的前几篇,你查看了msdb库下用于授权访问SQL Server代理的安全角色.这些角色包括SQLAgentUserRole.SQLAgentReaderRole和SQLAgentOperatorRole.每个角色授予用户一定的权限来使用SQL Server代理,而不必是sysadmin服务器角色的成员.为完全管理控制SQL Server代理,你仍然需要sysadmin角色的成员.此外,你回顾了SQL Server代理服务

第九篇 SQL Server代理了解作业和安全

本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这系列的前几篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本,甚至自己的程序.你最好的选择是使用PowerShell的子系统运行PowerShell脚本.PowerShell脚本将允许你处理几乎所有方面的Windows和SQL Server问题.在这一篇,你会深入到SQL Server代理安全.安全是个令人困惑的话题,它值得一些明确的考虑.这系列有两个不同方面

第七篇 SQL Server安全跨数据库所有权链接

本篇文章是SQL Server安全系列的第七篇,详细内容请参考原文. Relational databases are used in an amazing variety of applications with connections from a dizzying array of clients over widely distributed networks,特别是互联网,使得数据几乎向任何人,任何地方开放.数据库可以包含相当大部分的人类知识,包括高度敏感的个人信息和关键数据.数据库的

第八篇 SQL Server代理使用外部程序

本篇文章是SQL Server代理系列的第八篇,详细内容请参考原文 在这系列的前几篇,学习了如何用SQL Server代理作业活动监视器监控作业活动和查看作业历史记录.在实时监控和管理SQL Server代理作业上,作业活动监视器是一个很好的工具.第八篇,你会看到SQL Server代理的另一个功能——the ability to shell out to the operating system and run programs outside of the SQL Server enviro

SQL Server的权限管理和数据恢复

一.SQL Server权限设置 SQL Server与其他服务器不同,通常保存着运营.开发.市场等重要数据,其中大量数据还涉及机密.因此掌握SQL Server的权限设置是DBA必备的关键技能. 1.SQL Server的安全机制 SQL Server的安全性是建立在认证和访问许可两种安全机制之上的.其中,认证是用来确定登录SQL Server的用户的登录账号和密码是否正确,以此来验证其是否具有连接SQL Server的权限:访问许可用来授予用户或组能够在数据库中执行哪些操作,如创建表.查询数

第六篇 SQL Server代理深入作业步骤工作流

本篇文章是SQL Server代理系列的第六篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.每个作业步骤在技术上是独立的,但是你可以创建工作流贯穿作业中的各个步骤.在这篇文章中,你将学习如何在作业步骤中使用工作流来改变要执行的操作,单一作业有多个条件可以处理.你也会接触作业步骤安全和作业子系统的更多细节.SQL Server代理步骤如第二篇所述,SQL Server代理作业包含一个或多个作业步骤.每一个作业

第七篇 SQL Server代理作业活动监视器

本篇文章是SQL Server代理系列的第七篇,详细内容请参考原文 在这系列的前几篇,你创建并配置SQL Server代理作业.每个作业有一个或多个步骤,可能包含大量的工作流.在这篇文章中,将查看作业活动监视器.作业活动监视器是系统管理工具来运行工作,查看作业历史记录,并启用/禁用作业.本文同样会回顾一些作业活动监视器调用的存储过程,你可以直接调用过程做你自己的自定义任务监控.SQL Server代理作业活动监视器SQL Server代理作业活动监视器的主要机制是监视作业运行,以及查看代理已运行