6.4 服务器和数据库角色
在7.0版之前,SQL Server有过组的概念――这是用户权限的分组,你只需简单地把用户分配到组中,就能一次指派所有这些权限。这里的组与Windows中的组起作用的方式有很大不同,用户能够属于多个Windows组,因此,可以根据需要混合搭配它们。在SQL Server 6.5(和更早的版本)中,每一个数据库里,一个用户只允许属于一个组。
SQL Server 7.0之前版本的这种方式产生的后遗症是,SQL Server组属于以下3类之一:
l 经常根据用户级别的许可权限对它们进行修改;
l 它们只是主要的组的微小变形;
l 它们拥有多于所需的访问权限(以便使DBA的工作更为轻松)。
基本上,它们虽然很有必要,但同时也是一个很大的麻烦。
伴随7.0版的出现,在这方面发生了一些很大的变化。现在,用户属于一个角色,而非一个组。在最一般的意义上,角色与组是相同的事物。
角色是一组访问权限的集合,通过简单地把用户分配到那个角色中,就能将这一组访问权限一起指派给用户。
在这里,相似之处逐渐消失。使用角色时,用户能够一次属于多个角色。由于能够把访问权限组织到更小的和更合理的组中,然后把它们混合搭配为最适合用户的规则,这简直令人难以置信的便利。
角色分为两类:
l 服务器角色;
l 数据库角色。
很快,我们还将看到第三种称为角色的事物――应用程序角色,尽管我希望微软选用另外的名字。这是一种特殊的方式,用来把用户化名到不同的许可权限组中。应用程序角色不是分配用户的,它是一种让应用程序拥有的权限集不同于来自用户的权限集的方法。由于这个原因,我通常不认为应用程序角色是真正意义上的“角色”。
服务器角色限制在那些当发布SQL Server时就已经建立于其中的角色,并且,它在这里主要是为了进行系统的维护以及授予完成非数据库特有的事情的能力,如创建登录账户和创建链接服务器。
与服务器角色很类似,这里有一定数目的内置(或“固定”)数据库角色,不过,你也可以定义自己的数据库角色,以满足你独特的需求。数据库角色用来进行设置,以及在一个给定的数据库中分组特定的用户权限。
接下来,我们分别来看这两种类型的角色。
6.4.1 服务器角色
所有的服务器角色都是“固定的”角色,并且,从一开始就存在于那里――自安装完SQL Server的那一刻起,你将拥有的所有服务器角色就已经存在了。
对于在服务器上承担管理角色任务的单个用户,你可以对其混合搭配这些角色。一般来说,我怀疑只有最大型的数据库才会使用比sysadmin和securityadmin更多的角色,然而,有它们在旁边还是很便利的。
在本章的前面,我曾就全能用户会带来的麻烦进行过抨击。当新的sysadmin角色添加到7.0版时,我完全是欣喜若狂的,或许,得知此事你不会感到惊奇。sysadmin角色的存在表明,在不断发展的基础上,不再需要让所有人都有sa登录账户――只要让需要拥有那种访问级别的用户成为sysadmin角色的成员,这样他们就不再需要以sa登录。
6.4.2 数据库角色
数据库角色限制在单个数据库的范围之内――用户属于一个数据库中的db_datareader角色并不意味着他属于另一个数据库中的那个角色。数据库角色分为两个子类:固定数据库角色和用户定义数据库角色。
1.固定数据库角色
就如同存在若干个固定服务器角色一样,这里也有许多的固定数据库角色。他们中的一些有预先定义好的专门的用途,这是不能使用常规的语句复制出来的(即是说,你无法创建拥有同样功能的用户定义数据库角色)。然而,大多数角色的存在是为了处理更一般的情形,并让你做起事情来更加容易。
与使用固定服务器角色很类似,除非是在最大型的数据库中,否则,你可能不会使用到所有这些角色。在这些固定数据库角色中,一些是无法用你自己的数据库角色来替换的,而另一些,只不过在处理那些似乎经常出现的简单粗糙的情形时非常便利而已。
2.用户定义数据库角色
实际上,可供使用的固定角色只是为了帮助你开始入手。安全性真正的中流砥柱是用户定义数据库角色的创建和分配。对于这些角色来说,由你来决定它们将包含什么许可权限。
使用用户定义角色时,可以像针对单独的用户那样,用完全相同的方式进行GRANT、DENY和REVOKE。关于使用角色,好的事情是,用户往往归入访问需要的范畴――通过使用角色,你能够在一个地方做改动,并将改动散播给所有类似的用户(至少被指派到那个角色的用户)。
● 创建用户定义角色
我们使用sp_addrole系统存储过程来创建我们自己的角色。其语法非常简单:
sp_addrole [@rolename =] <'角色名'>
[,[@ownername =] <'所有者'>]
role name只不过是想要用来称呼那个角色的名称。常见的命名模式的例子包括:以部门来命名(Accounting、Sales、Marketing等),或者以具体的工作来命名(CustomerService、Salesperson、President等)。使用这样的角色的确能够让向系统中添加新用户的工作变得容易。如果会计部门新近雇用了某人,你只需把他(或她)添加到Accounting角色中(或者,如果更加精确,甚至可以是AccountsPayable角色),然后,就可以丢开这件事了――无需研究“这个人应当具有什么权限呢?”
此处的owner与系统中所有其他对象上的owner是相同的事物。默认是数据库的所有者,并且,我强烈建议让它保持那样(换句话说,只需忽略这个可选参数即可)。
接下来,创建我们自己的角色:
![]()
当执行上面的语句时,将返回给你一个友好的消息,告诉你新的角色已经加入。
现在,我们需要为这个角色实际指派一些权限,以这种方式为这个角色增加一些价值。要完成这一任务,只需像本章前面对实际的用户所做的那样,使用GRANT、DENY或REVOKE语句:
![]()
现在,所有属于我们角色的人都拥有了到Territories表的SELECT访问权限(除非在他们的安全性信息中的其他地方有DENY)。
此刻,已经准备好添加用户了。
● 向角色中添加用户
有了所有这些角色固然不错,但是,如果没有把任何人指派给他们,则角色将没什么用处。向角色中添加用户非常简单,就是使用系统存储过程sp_addrolemember并提供数据库名和登录ID:
sp_addrolemember [@rolename =] <角色名>,
[@membername =] <登录ID>
关于该存储过程的参数,一切都是非常一目了然的,因此,我们直接进入一个例子。
先从证实TestAccount不具有到Territories表的访问权限开始:
![]()
果不其然,我们被拒绝了(眼下尚没有访问的权限):
![]()
现在,把我们的Windows用户TestAccount添加到OurTestRole角色中:
![]()
同样,我们收到一条确认消息,告知事情正确完成了:
![]()
此时,到了再次尝试并运行SELECT语句的时候了――这一次顺利得多(会得到大约53个返回行)。
● 从角色中删除用户
有起必有落,添加到角色中的用户势必也将从角色中删除。
从角色中删除用户的操作与把用户添加到角色中的操作几乎一样,只不过这里使用的是一个名为sp_droprolemember的不同的存储过程,使用的形式如下:
sp_droprolemember [@rolename =] <角色名>,
[@membername =] <安全账号>
接下来,返回到我们的例子,并从OurTestRole数据库角色中删除TestAccount:
![]()
你会收到另一个确认消息,告知一切顺利。现在,再试试我们的SELECT语句:
![]()
果然,我们又一次收到了说明我们没有访问权限的错误消息。
可以用这种方式向任何角色中添加用户以及从任何角色中删除用户――角色是用户定义角色还是固定角色并不重要,是服务器角色还是数据库角色也没什么关系。无论在什么情况下,它们的操作几乎完全一样。
还要注意的是,所有这些工作都可以在Management Studio中进行。要更改与角色相关联的权限,只需单击数据库结点的角色成员,然后使用复选框指派权限即可。当想要向角色中添加用户时,只需去到用户的属性对话框中,选择服务器或数据库角色选项卡,然后,在所有想要用户拥有其角色成员身份的角色上打上勾号。
● 删除角色
删除角色与添加角色一样容易。其语法很简单:
EXEC sp_droprole <'角色名'>
执行后,角色就被删除了。
|