用户和角色
对于数据库管理员们来说,安全问题至关重要,他们一直设法保护他们不计其数的重要业务数据,以免被那些没有权利却又试图超越权限的内部人员或外部人员窥视外泄。所有的关系数据库系统都提供了某种内在的安全机制设计来尽量减少这些威胁。这些安全机制包括从Microsoft Access提供的简单口令保护到一些像Oracle和Microsoft SQL Server这样的高级关系数据库所支持的复杂的用户/角色结构。本文将着重介绍对所有执行SQL语言的数据库都很常见的安全机制。同时,我们还将顺带了解一下加强数据访问控制,保证数据安全的机制。
基于服务器的数据库都支持用户(user)这个概念,类似于计算机操作系统中使用的用户概念一样。如果你对于Microsoft Windows NT和Windows 2000里的用户/组等层次结构都很熟悉的话,你会发现SQL Server和Oracle所支持的用户/角色的分组非常类似。
强烈建议你为访问你数据库的每一个人创建一个个人数据库用户帐号。虽然不同的用户之间共享帐号,或者只为需要访问数据库的每种类型用户创建一个用户帐号,在技术上都是可行的,但是这种做法对于数据库安全来说并不妥当,原因有二:其一,这种做法会消除个人应负的责任——如果某恶意用户篡改了你的数据库(例如给他自己的银行帐号支付了一万块钱),你就不可能通过查看审计日志来追踪到具体的是哪个人做的;其二,如果某个特定用户离开了你所在的机构,而你想要删除他访问数据库的权限,那么你只能强制修改该组所有用户都在使用的登录口令才行。
在不同的操作平台里,创建用户帐号的方法也不同,你可能需要查阅你所用的特定数据库管理系统的说明书才能找到确切的创建程序。Microsoft SQL Server的用户应该参照关于sp_adduser存储程序的具体用法。而对Oracle数据库管理员来说有用的可能是CREATE USER 命令。你还应该了解一下系统可选的登录认证方案。例如,Microsoft SQL Server支持使用Windows NT的集成安全设置。在这个安全方案设置下,会通过Windows NT用户帐号来识别连接到数据库的用户,因此在访问数据库的时候不用再另外输入用户登录帐号和口令。这个模式极受数据库管理员的钟爱,因为这种方式把帐号管理的重担卸给了网络管理人员,而且为实现终端用户的单点登录提供了便利。
如果你的运行环境里只有少量用户,那么你可能会发现,直接为他们创建用户帐号并分配权限就能满足你的需要了。不过,如果你拥有大量用户,你很可能会被维护帐号和管理分配适当权限的重担压得喘不过气来。关系数据库所支持的“角色”(role)概念就是用来减轻这个负担的。管理员可以先把同组的用户帐号集中到一个角色单元中,然后把该角色作为一个整体来分配权限,而不再单为每个用户分配权限。例如,我们可以创建一个数据库管理员角色,然后把我们所有管理人员的用户帐号添加到这个角色中。这个步骤完成后,我们只需给这个角色分配好权限,也就相当于为全部现有(以及将来)的管理员分配了具体权限。同样的,根据操作平台的不同,创建角色的程序也是不同的。MS SQL Server的管理员应该参照sp_addrole存储程序,而Oracle的数据库管理员应该使用CREATE ROLE命令。
一旦你的数据库已经有用户和角色进驻了,就是时候开始分配权限了。下面将主要讨论权限分配的问题。
权限设置
现在我们已经把用户都添加到我们的数据库了,该开始设置用户权限以加强数据库的安全性了。第一个步骤就是授予我们的数据库用户适当的权限。通过执行SQL GRANT语句就可以完成这个任务。该命
的语法如下:
值得一提的是 Microsoft SQL Server 还支持另外一种类似撤销机制—— DENY (拒绝)命令。即时用户现在或者将来通过角色设置的关系拥有了某种权限,这个命令也可以用来明确的拒绝该用户执行这个权限。该命令语法如下:
回到刚才的例子,假设 Linlin 也是同样拥有访问 Customers 表权利的 Managers 角色中的一员。前面的 REVOKE 命令就可能不足以制止他访问该数据表。通过专门对他的用户帐号使用 GRANT 语句可以撤销之前赋予他的权限,但是不会影响到他通过其帐号所在的 Managers 角色组中获得的权限。如果我们使用 DENY 语句,就能够阻止他从角色里承继的权限。命令如下: 事实上, DENY 命令在数据库访问控制中创建了一种“负权限”。如果我们随后又决定要赋予 Linlin 从 Customers 删除行的权限,我们就不能简单的用 GRANT 命令来实现了。已经存在的 DENY 命令比 GRANT 命令的优先级更高。相反,我们先要用 REVOKE 命令来撤销已进驻的负权限,命令如下: 你大概已经发现该命令和之前用来撤销正权限所用的命令一摸一样。记住 DENY 和 GRANT 命令都是用同样的方式运行的,他们都是在数据库访问控制机制里创建权限(无论是正权限还是负权限)。 REVOKE 命令可以撤销某个特定用户所有的正权限和负权限。如果 Linlin 是拥有从数据表中删除行权限的角色中的一员的话,一但执行了这个命令,他就拥有了上述的权限。
看完以上所有内容,相信你已经学到了不少关于用 SQL 进行访问权控制机制的知识。即便如此,你还是应该参考你的数据库管理系统说明书,了解更多如何加强安全保护的措施。你会发现很多数据库支持更加高级的访问控制机制,例如如何针对特定的列进行权限设置之类的。
GRANT SELECT, INSERT, UPDATE ON Customers TO DataEntry |
GRANT CREATE TABLE TO DBA WITH GRANT OPTION |
REVOKE DELETE ON Customers FROM Linlin |
REVOKE [GRANT OPTION FOR] <permissions> ON <table> FROM <user/role> |
可能你已经注意到这个命令的语法类似于
GRANT
命令。唯一的不同之处在于
WITH GRANT OPTION
是在
REVOKE
命令行做的声明而不是在命令的末尾。
还是通过例子来说明吧,假设我们撤销之前赋予用户
Linlin
从
Customers
数据库中删除记录的权限,命令如下:
REVOKE DELETE ON Customers FROM Linlin |
值得一提的是 Microsoft SQL Server 还支持另外一种类似撤销机制—— DENY (拒绝)命令。即时用户现在或者将来通过角色设置的关系拥有了某种权限,这个命令也可以用来明确的拒绝该用户执行这个权限。该命令语法如下:
回到刚才的例子,假设 Linlin 也是同样拥有访问 Customers 表权利的 Managers 角色中的一员。前面的 REVOKE 命令就可能不足以制止他访问该数据表。通过专门对他的用户帐号使用 GRANT 语句可以撤销之前赋予他的权限,但是不会影响到他通过其帐号所在的 Managers 角色组中获得的权限。如果我们使用 DENY 语句,就能够阻止他从角色里承继的权限。命令如下: 事实上, DENY 命令在数据库访问控制中创建了一种“负权限”。如果我们随后又决定要赋予 Linlin 从 Customers 删除行的权限,我们就不能简单的用 GRANT 命令来实现了。已经存在的 DENY 命令比 GRANT 命令的优先级更高。相反,我们先要用 REVOKE 命令来撤销已进驻的负权限,命令如下: 你大概已经发现该命令和之前用来撤销正权限所用的命令一摸一样。记住 DENY 和 GRANT 命令都是用同样的方式运行的,他们都是在数据库访问控制机制里创建权限(无论是正权限还是负权限)。 REVOKE 命令可以撤销某个特定用户所有的正权限和负权限。如果 Linlin 是拥有从数据表中删除行权限的角色中的一员的话,一但执行了这个命令,他就拥有了上述的权限。
看完以上所有内容,相信你已经学到了不少关于用 SQL 进行访问权控制机制的知识。即便如此,你还是应该参考你的数据库管理系统说明书,了解更多如何加强安全保护的措施。你会发现很多数据库支持更加高级的访问控制机制,例如如何针对特定的列进行权限设置之类的。
DENY <permissions> ON <table> TO <user/role> |
DENY DELETE ON Customers TO Linlin |
REVOKE DELETE ON Customers FROM Linlin |
GRANT <permissions> [ON <table>] TO <user/role> [WITH GRANT OPTION] |