第四篇 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, '');
- 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安全权限的更多相关文章
- 【译】第四篇 SQL Server安全权限
本篇文章是SQL Server安全系列的第四篇,详细内容请参考原文. 权限授予主体访问对象,以执行某些操作.SQL Server有大量你可以授予给主体的权限,你甚至可以拒绝或回收权限.这听起来有点复杂 ...
- 第四篇 SQL Server代理配置数据库邮件
本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Serve ...
- 【译】第四篇 SQL Server代理配置数据库邮件
本篇文章是SQL Server代理系列的第四篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.SQL Serve ...
- 第五篇 SQL Server代理理解代理错误日志
本篇文章是SQL Server代理系列的第五篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.在第四篇中我们看到 ...
- 【译】第五篇 SQL Server代理理解代理错误日志
本篇文章是SQL Server代理系列的第五篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.在第四篇中我们看到 ...
- 第十篇 SQL Server代理使用代理帐户
本篇文章是SQL Server代理系列的第十篇,详细内容请参考原文 在这一系列的上一篇,你查看了msdb库下用于授权访问SQL Server代理的安全角色.这些角色包括SQLAgentUserRole ...
- 第九篇 SQL Server代理了解作业和安全
本篇文章是SQL Server代理系列的第九篇,详细内容请参考原文 在这一系列的上一篇,学习了如何在SQL Server代理作业步骤启动外部程序.你可以使用过时的ActiveX系统,运行批处理命令脚本 ...
- 第七篇 SQL Server安全跨数据库所有权链接
本篇文章是SQL Server安全系列的第七篇,详细内容请参考原文. Relational databases are used in an amazing variety of applicatio ...
- 第八篇 SQL Server代理使用外部程序
本篇文章是SQL Server代理系列的第八篇,详细内容请参考原文 在这一系列的上一篇,学习了如何用SQL Server代理作业活动监视器监控作业活动和查看作业历史记录.在实时监控和管理SQL Ser ...
随机推荐
- java获取MySQL自动的int类型的Id
@Resource(name = "dashboardTemplate") protected JdbcTemplate systemJDBCTemplate; //这个是Dao里 ...
- Hibernate + proxool 连接数超过最大允许连接数
主要原因是操作完成没有释放连接,在Hibernate中增加设定 <prop key="hibernate.connection.release_mode">after_ ...
- FAQ软件卸载
今天安装了一个PDF 编辑软件pdftk,下载时提示有50多M,感觉不好用,卸载后提示释放空间只有2M,郁闷了.上网查寻,如下命令 sudo dpkg -p package_name卸载软件包及其配置 ...
- Yii源码阅读笔记(六)
组件(component),是Yii框架的基类,实现了属性.事件.行为三类功能,如果需要事件和行为的功能,需要继承该类,不需要可直接继承Object类: namespace yii\base; use ...
- Bootstrap页面布局18 - BS导航路径以及分页器
导航路径:又叫“面包屑”,功能是让用户知道所处的位置. <!--面包屑--> <ul class='breadcrumb'> <li><a href='#'& ...
- Bootstrap页面布局13 - BS按钮
bootstrap中的按钮类 一般可以作为按钮的标签有:<a></a> <button></button> <input type='butt ...
- 4 bytes (32 bits) or 8 bytes (64 bits)
Computer Systems A Programmer's Perspective Second Edition BusesRunning throughout the system is a c ...
- 如何获取DIV的id
$(obj).attr("id");参数可以是id也可以是其他例如name等属性
- svn截图
一.合并一个范围的版本 此类型应用最为广泛,主要是把分支中的修改合并到主干上来.在主干上点击右键选择合并,然后选择合并类型:合并一个范围的版本.合并的源URL填写的是要合并的分支的URL,待合 ...
- 修改MyEclipse默认的Servlet和jsp代码模板
一.修改Servlet的默认模板代码 使用MyEclipse创建Servlet时,根据默认的Servlet模板生成的Servlet代码如下: 1 package gacl.servlet.study; ...