6.4 服务器和数据库角色
 

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

该角色能够执行SQL Server上的任何操作。本质上,任何具有这种角色成员身份的人都是那个服务器上的sa。这种服务器角色的创建为微软提供了某一天去除sa登录的能力——实际上,联机丛书把sa称作本质上为遗留物的东西

值得注意的是,在SQL Server上,Windows的Administrators组被自动映射到sysadmin角色中。这意味着服务器的Administrators组中的任何成员同时也具有对SQL数据的sa级别的访问权限。如果需要,你可以从sysadmin角色中删除Windows的administrators组,以提高安全性、防范漏洞

serveradmin

该角色能设置服务器范围的配置选项或关闭服务器。尽管它在范围上相当有限,但是,由该角色的成员所控制的功能对于服务器的性能会产生非常重大的影响

setupadmin

该角色仅限于管理链接服务器和启动过程

securityadmin

对于专门创建出来用于管理登录名、读取错误日志和创建数据库许可权限的登录名来说,该角色非常便利。在很多方面,该角色是典型的系统操作员角色——它能够处理多数的日常事务,但是,却不具备一个真正无所不能的超级用户所拥有的那种全局访问

processadmin

能够管理SQL Server中运行的进程——必要的话,该角色能够终止长时间运行的进程

dbcreator

该角色仅限于创建和更改数据库

diskadmin

管理磁盘文件(指派给了什么文件组、附加和分离数据库,等等)

bulkadmin

该角色有些怪异。它被明确创建出来,用于执行BULK INSERT语句的权限,否则的话,只能由具有sysadmin权限的人来执行BULK INSERT语句。坦白地说,我不明白为什么该语句不能像其他事情那样通过GRANT命令来授予权限,但它的确没有。要记住,即使把一个用户加入到了bulkadmin组中,也只是给了他们访问那个语句的权限,对于运行该语句的表,并没有授予用户访问那个表的权限。这意味着不仅需要把用户添加到bulkadmin中,而且,对于想要用户能在其上执行BULK INSERT的表,还要授予(GRANT)用户INSERT许可权限。此外,对于将在BULK INSERT语句中引用的所有表,还要确保用户拥有正确的到那些表的SELECT访问权限

对于在服务器上承担管理角色任务的单个用户,你可以对其混合搭配这些角色。一般来说,我怀疑只有最大型的数据库才会使用比sysadmin和securityadmin更多的角色,然而,有它们在旁边还是很便利的。

在本章的前面,我曾就全能用户会带来的麻烦进行过抨击。当新的sysadmin角色添加到7.0版时,我完全是欣喜若狂的,或许,得知此事你不会感到惊奇。sysadmin角色的存在表明,在不断发展的基础上,不再需要让所有人都有sa登录账户——只要让需要拥有那种访问级别的用户成为sysadmin角色的成员,这样他们就不再需要以sa登录。

6.4.2  数据库角色

数据库角色限制在单个数据库的范围之内——用户属于一个数据库中的db_datareader角色并不意味着他属于另一个数据库中的那个角色。数据库角色分为两个子类:固定数据库角色和用户定义数据库角色。

1.固定数据库角色

就如同存在若干个固定服务器角色一样,这里也有许多的固定数据库角色。他们中的一些有预先定义好的专门的用途,这是不能使用常规的语句复制出来的(即是说,你无法创建拥有同样功能的用户定义数据库角色)。然而,大多数角色的存在是为了处理更一般的情形,并让你做起事情来更加容易。

角  色

特  性

db_owner

该角色表现得就好像它是所有其他数据库角色中的成员一样。使用这一角色能够造就这样的情形:多个用户可以完成相同的功能和任务,就好像他们是数据库的所有者一样

db_accessadmin

实现类似于securityadmin服务器角色所实现功能的一部分,只不过这一角色仅局限于指派它并创建用户的单个数据库中(不是单个的权限)。它不能创建新的SQL Server登录账户,但是,该角色中的成员能够把Windows用户和组以及现有的SQL Server登录账户加入到数据库中

db_datareader

能够在数据库中所有的用户表上执行SELECT语句

db_datawriter

能够在数据库中所有的用户表上执行INSERT、UPDATE和DELETE语句

db_ddladmin

能够在数据库中添加、修改或删除对象

db_securityadmin

securityadmin服务器角色的数据库级别的等价物。这一数据库角色不能在数据库中创建新的用户,但是,能够管理角色和数据库角色的成员,并能在数据库中管理语句和对象的许可权限

db_backupoperator

备份数据库(打赌你不会想到那样一个角色!)

db_denydatareader

提供一种等同于在数据库中所有表和视图上DENY SELECT的效果

db_denydatawriter

类似于db_denydatareader,只不过这里影响的是INSERT、UPDATE和DELETE语句

与使用固定服务器角色很类似,除非是在最大型的数据库中,否则,你可能不会使用到所有这些角色。在这些固定数据库角色中,一些是无法用你自己的数据库角色来替换的,而另一些,只不过在处理那些似乎经常出现的简单粗糙的情形时非常便利而已。

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 <'角色名'>

执行后,角色就被删除了。