6.4 服務(wù)器和數(shù)據(jù)庫(kù)角色
在7.0版之前,SQL Server有過(guò)組的概念——這是用戶權(quán)限的分組,你只需簡(jiǎn)單地把用戶分配到組中,就能一次指派所有這些權(quán)限。這里的組與Windows中的組起作用的方式有很大不同,用戶能夠?qū)儆诙鄠€(gè)Windows組,因此,可以根據(jù)需要混合搭配它們。在SQL Server 6.5(和更早的版本)中,每一個(gè)數(shù)據(jù)庫(kù)里,一個(gè)用戶只允許屬于一個(gè)組。
SQL Server 7.0之前版本的這種方式產(chǎn)生的后遺癥是,SQL Server組屬于以下3類之一:
l 經(jīng)常根據(jù)用戶級(jí)別的許可權(quán)限對(duì)它們進(jìn)行修改;
l 它們只是主要的組的微小變形;
l 它們擁有多于所需的訪問(wèn)權(quán)限(以便使DBA的工作更為輕松)。
基本上,它們雖然很有必要,但同時(shí)也是一個(gè)很大的麻煩。
伴隨7.0版的出現(xiàn),在這方面發(fā)生了一些很大的變化。現(xiàn)在,用戶屬于一個(gè)角色,而非一個(gè)組。在最一般的意義上,角色與組是相同的事物。
角色是一組訪問(wèn)權(quán)限的集合,通過(guò)簡(jiǎn)單地把用戶分配到那個(gè)角色中,就能將這一組訪問(wèn)權(quán)限一起指派給用戶。
在這里,相似之處逐漸消失。使用角色時(shí),用戶能夠一次屬于多個(gè)角色。由于能夠把訪問(wèn)權(quán)限組織到更小的和更合理的組中,然后把它們混合搭配為最適合用戶的規(guī)則,這簡(jiǎn)直令人難以置信的便利。
角色分為兩類:
l 服務(wù)器角色;
l 數(shù)據(jù)庫(kù)角色。
很快,我們還將看到第三種稱為角色的事物——應(yīng)用程序角色,盡管我希望微軟選用另外的名字。這是一種特殊的方式,用來(lái)把用戶化名到不同的許可權(quán)限組中。應(yīng)用程序角色不是分配用戶的,它是一種讓?xiě)?yīng)用程序擁有的權(quán)限集不同于來(lái)自用戶的權(quán)限集的方法。由于這個(gè)原因,我通常不認(rèn)為應(yīng)用程序角色是真正意義上的“角色”。
服務(wù)器角色限制在那些當(dāng)發(fā)布SQL Server時(shí)就已經(jīng)建立于其中的角色,并且,它在這里主要是為了進(jìn)行系統(tǒng)的維護(hù)以及授予完成非數(shù)據(jù)庫(kù)特有的事情的能力,如創(chuàng)建登錄賬戶和創(chuàng)建鏈接服務(wù)器。
與服務(wù)器角色很類似,這里有一定數(shù)目的內(nèi)置(或“固定”)數(shù)據(jù)庫(kù)角色,不過(guò),你也可以定義自己的數(shù)據(jù)庫(kù)角色,以滿足你獨(dú)特的需求。數(shù)據(jù)庫(kù)角色用來(lái)進(jìn)行設(shè)置,以及在一個(gè)給定的數(shù)據(jù)庫(kù)中分組特定的用戶權(quán)限。
接下來(lái),我們分別來(lái)看這兩種類型的角色。
6.4.1 服務(wù)器角色
所有的服務(wù)器角色都是“固定的”角色,并且,從一開(kāi)始就存在于那里——自安裝完SQL Server的那一刻起,你將擁有的所有服務(wù)器角色就已經(jīng)存在了。
角 色
|
特 性
|
sysadmin
|
該角色能夠執(zhí)行SQL Server上的任何操作。本質(zhì)上,任何具有這種角色成員身份的人都是那個(gè)服務(wù)器上的sa。這種服務(wù)器角色的創(chuàng)建為微軟提供了某一天去除sa登錄的能力——實(shí)際上,聯(lián)機(jī)叢書(shū)把sa稱作本質(zhì)上為遺留物的東西
值得注意的是,在SQL Server上,Windows的Administrators組被自動(dòng)映射到sysadmin角色中。這意味著服務(wù)器的Administrators組中的任何成員同時(shí)也具有對(duì)SQL數(shù)據(jù)的sa級(jí)別的訪問(wèn)權(quán)限。如果需要,你可以從sysadmin角色中刪除Windows的administrators組,以提高安全性、防范漏洞
|
serveradmin
|
該角色能設(shè)置服務(wù)器范圍的配置選項(xiàng)或關(guān)閉服務(wù)器。盡管它在范圍上相當(dāng)有限,但是,由該角色的成員所控制的功能對(duì)于服務(wù)器的性能會(huì)產(chǎn)生非常重大的影響
|
setupadmin
|
該角色僅限于管理鏈接服務(wù)器和啟動(dòng)過(guò)程
|
securityadmin
|
對(duì)于專門(mén)創(chuàng)建出來(lái)用于管理登錄名、讀取錯(cuò)誤日志和創(chuàng)建數(shù)據(jù)庫(kù)許可權(quán)限的登錄名來(lái)說(shuō),該角色非常便利。在很多方面,該角色是典型的系統(tǒng)操作員角色——它能夠處理多數(shù)的日常事務(wù),但是,卻不具備一個(gè)真正無(wú)所不能的超級(jí)用戶所擁有的那種全局訪問(wèn)
|
processadmin
|
能夠管理SQL Server中運(yùn)行的進(jìn)程——必要的話,該角色能夠終止長(zhǎng)時(shí)間運(yùn)行的進(jìn)程
|
dbcreator
|
該角色僅限于創(chuàng)建和更改數(shù)據(jù)庫(kù)
|
diskadmin
|
管理磁盤(pán)文件(指派給了什么文件組、附加和分離數(shù)據(jù)庫(kù),等等)
|
bulkadmin
|
該角色有些怪異。它被明確創(chuàng)建出來(lái),用于執(zhí)行BULK INSERT語(yǔ)句的權(quán)限,否則的話,只能由具有sysadmin權(quán)限的人來(lái)執(zhí)行BULK INSERT語(yǔ)句。坦白地說(shuō),我不明白為什么該語(yǔ)句不能像其他事情那樣通過(guò)GRANT命令來(lái)授予權(quán)限,但它的確沒(méi)有。要記住,即使把一個(gè)用戶加入到了bulkadmin組中,也只是給了他們?cè)L問(wèn)那個(gè)語(yǔ)句的權(quán)限,對(duì)于運(yùn)行該語(yǔ)句的表,并沒(méi)有授予用戶訪問(wèn)那個(gè)表的權(quán)限。這意味著不僅需要把用戶添加到bulkadmin中,而且,對(duì)于想要用戶能在其上執(zhí)行BULK INSERT的表,還要授予(GRANT)用戶INSERT許可權(quán)限。此外,對(duì)于將在BULK INSERT語(yǔ)句中引用的所有表,還要確保用戶擁有正確的到那些表的SELECT訪問(wèn)權(quán)限
|
對(duì)于在服務(wù)器上承擔(dān)管理角色任務(wù)的單個(gè)用戶,你可以對(duì)其混合搭配這些角色。一般來(lái)說(shuō),我懷疑只有最大型的數(shù)據(jù)庫(kù)才會(huì)使用比sysadmin和securityadmin更多的角色,然而,有它們?cè)谂赃呥€是很便利的。
在本章的前面,我曾就全能用戶會(huì)帶來(lái)的麻煩進(jìn)行過(guò)抨擊。當(dāng)新的sysadmin角色添加到7.0版時(shí),我完全是欣喜若狂的,或許,得知此事你不會(huì)感到驚奇。sysadmin角色的存在表明,在不斷發(fā)展的基礎(chǔ)上,不再需要讓所有人都有sa登錄賬戶——只要讓需要擁有那種訪問(wèn)級(jí)別的用戶成為sysadmin角色的成員,這樣他們就不再需要以sa登錄。
6.4.2 數(shù)據(jù)庫(kù)角色
數(shù)據(jù)庫(kù)角色限制在單個(gè)數(shù)據(jù)庫(kù)的范圍之內(nèi)——用戶屬于一個(gè)數(shù)據(jù)庫(kù)中的db_datareader角色并不意味著他屬于另一個(gè)數(shù)據(jù)庫(kù)中的那個(gè)角色。數(shù)據(jù)庫(kù)角色分為兩個(gè)子類:固定數(shù)據(jù)庫(kù)角色和用戶定義數(shù)據(jù)庫(kù)角色。
1.固定數(shù)據(jù)庫(kù)角色
就如同存在若干個(gè)固定服務(wù)器角色一樣,這里也有許多的固定數(shù)據(jù)庫(kù)角色。他們中的一些有預(yù)先定義好的專門(mén)的用途,這是不能使用常規(guī)的語(yǔ)句復(fù)制出來(lái)的(即是說(shuō),你無(wú)法創(chuàng)建擁有同樣功能的用戶定義數(shù)據(jù)庫(kù)角色)。然而,大多數(shù)角色的存在是為了處理更一般的情形,并讓你做起事情來(lái)更加容易。
角 色
|
特 性
|
db_owner
|
該角色表現(xiàn)得就好像它是所有其他數(shù)據(jù)庫(kù)角色中的成員一樣。使用這一角色能夠造就這樣的情形:多個(gè)用戶可以完成相同的功能和任務(wù),就好像他們是數(shù)據(jù)庫(kù)的所有者一樣
|
db_accessadmin
|
實(shí)現(xiàn)類似于securityadmin服務(wù)器角色所實(shí)現(xiàn)功能的一部分,只不過(guò)這一角色僅局限于指派它并創(chuàng)建用戶的單個(gè)數(shù)據(jù)庫(kù)中(不是單個(gè)的權(quán)限)。它不能創(chuàng)建新的SQL Server登錄賬戶,但是,該角色中的成員能夠把Windows用戶和組以及現(xiàn)有的SQL Server登錄賬戶加入到數(shù)據(jù)庫(kù)中
|
db_datareader
|
能夠在數(shù)據(jù)庫(kù)中所有的用戶表上執(zhí)行SELECT語(yǔ)句
|
db_datawriter
|
能夠在數(shù)據(jù)庫(kù)中所有的用戶表上執(zhí)行INSERT、UPDATE和DELETE語(yǔ)句
|
db_ddladmin
|
能夠在數(shù)據(jù)庫(kù)中添加、修改或刪除對(duì)象
|
db_securityadmin
|
securityadmin服務(wù)器角色的數(shù)據(jù)庫(kù)級(jí)別的等價(jià)物。這一數(shù)據(jù)庫(kù)角色不能在數(shù)據(jù)庫(kù)中創(chuàng)建新的用戶,但是,能夠管理角色和數(shù)據(jù)庫(kù)角色的成員,并能在數(shù)據(jù)庫(kù)中管理語(yǔ)句和對(duì)象的許可權(quán)限
|
db_backupoperator
|
備份數(shù)據(jù)庫(kù)(打賭你不會(huì)想到那樣一個(gè)角色!)
|
db_denydatareader
|
提供一種等同于在數(shù)據(jù)庫(kù)中所有表和視圖上DENY SELECT的效果
|
db_denydatawriter
|
類似于db_denydatareader,只不過(guò)這里影響的是INSERT、UPDATE和DELETE語(yǔ)句
|
與使用固定服務(wù)器角色很類似,除非是在最大型的數(shù)據(jù)庫(kù)中,否則,你可能不會(huì)使用到所有這些角色。在這些固定數(shù)據(jù)庫(kù)角色中,一些是無(wú)法用你自己的數(shù)據(jù)庫(kù)角色來(lái)替換的,而另一些,只不過(guò)在處理那些似乎經(jīng)常出現(xiàn)的簡(jiǎn)單粗糙的情形時(shí)非常便利而已。
2.用戶定義數(shù)據(jù)庫(kù)角色
實(shí)際上,可供使用的固定角色只是為了幫助你開(kāi)始入手。安全性真正的中流砥柱是用戶定義數(shù)據(jù)庫(kù)角色的創(chuàng)建和分配。對(duì)于這些角色來(lái)說(shuō),由你來(lái)決定它們將包含什么許可權(quán)限。
使用用戶定義角色時(shí),可以像針對(duì)單獨(dú)的用戶那樣,用完全相同的方式進(jìn)行GRANT、DENY和REVOKE。關(guān)于使用角色,好的事情是,用戶往往歸入訪問(wèn)需要的范疇——通過(guò)使用角色,你能夠在一個(gè)地方做改動(dòng),并將改動(dòng)散播給所有類似的用戶(至少被指派到那個(gè)角色的用戶)。
● 創(chuàng)建用戶定義角色
我們使用sp_addrole系統(tǒng)存儲(chǔ)過(guò)程來(lái)創(chuàng)建我們自己的角色。其語(yǔ)法非常簡(jiǎn)單:
sp_addrole [@rolename =] <'角色名'>
[,[@ownername =] <'所有者'>]
role name只不過(guò)是想要用來(lái)稱呼那個(gè)角色的名稱。常見(jiàn)的命名模式的例子包括:以部門(mén)來(lái)命名(Accounting、Sales、Marketing等),或者以具體的工作來(lái)命名(CustomerService、Salesperson、President等)。使用這樣的角色的確能夠讓向系統(tǒng)中添加新用戶的工作變得容易。如果會(huì)計(jì)部門(mén)新近雇用了某人,你只需把他(或她)添加到Accounting角色中(或者,如果更加精確,甚至可以是AccountsPayable角色),然后,就可以丟開(kāi)這件事了——無(wú)需研究“這個(gè)人應(yīng)當(dāng)具有什么權(quán)限呢?”
此處的owner與系統(tǒng)中所有其他對(duì)象上的owner是相同的事物。默認(rèn)是數(shù)據(jù)庫(kù)的所有者,并且,我強(qiáng)烈建議讓它保持那樣(換句話說(shuō),只需忽略這個(gè)可選參數(shù)即可)。
接下來(lái),創(chuàng)建我們自己的角色:

當(dāng)執(zhí)行上面的語(yǔ)句時(shí),將返回給你一個(gè)友好的消息,告訴你新的角色已經(jīng)加入。
現(xiàn)在,我們需要為這個(gè)角色實(shí)際指派一些權(quán)限,以這種方式為這個(gè)角色增加一些價(jià)值。要完成這一任務(wù),只需像本章前面對(duì)實(shí)際的用戶所做的那樣,使用GRANT、DENY或REVOKE語(yǔ)句:

現(xiàn)在,所有屬于我們角色的人都擁有了到Territories表的SELECT訪問(wèn)權(quán)限(除非在他們的安全性信息中的其他地方有DENY)。
此刻,已經(jīng)準(zhǔn)備好添加用戶了。
● 向角色中添加用戶
有了所有這些角色固然不錯(cuò),但是,如果沒(méi)有把任何人指派給他們,則角色將沒(méi)什么用處。向角色中添加用戶非常簡(jiǎn)單,就是使用系統(tǒng)存儲(chǔ)過(guò)程sp_addrolemember并提供數(shù)據(jù)庫(kù)名和登錄ID:
sp_addrolemember [@rolename =] <角色名>,
[@membername =] <登錄ID>
關(guān)于該存儲(chǔ)過(guò)程的參數(shù),一切都是非常一目了然的,因此,我們直接進(jìn)入一個(gè)例子。
先從證實(shí)TestAccount不具有到Territories表的訪問(wèn)權(quán)限開(kāi)始:

果不其然,我們被拒絕了(眼下尚沒(méi)有訪問(wèn)的權(quán)限):

現(xiàn)在,把我們的Windows用戶TestAccount添加到OurTestRole角色中:

同樣,我們收到一條確認(rèn)消息,告知事情正確完成了:

此時(shí),到了再次嘗試并運(yùn)行SELECT語(yǔ)句的時(shí)候了——這一次順利得多(會(huì)得到大約53個(gè)返回行)。
● 從角色中刪除用戶
有起必有落,添加到角色中的用戶勢(shì)必也將從角色中刪除。
從角色中刪除用戶的操作與把用戶添加到角色中的操作幾乎一樣,只不過(guò)這里使用的是一個(gè)名為sp_droprolemember的不同的存儲(chǔ)過(guò)程,使用的形式如下:
sp_droprolemember [@rolename =] <角色名>,
[@membername =] <安全賬號(hào)>
接下來(lái),返回到我們的例子,并從OurTestRole數(shù)據(jù)庫(kù)角色中刪除TestAccount:

你會(huì)收到另一個(gè)確認(rèn)消息,告知一切順利。現(xiàn)在,再試試我們的SELECT語(yǔ)句:

果然,我們又一次收到了說(shuō)明我們沒(méi)有訪問(wèn)權(quán)限的錯(cuò)誤消息。
可以用這種方式向任何角色中添加用戶以及從任何角色中刪除用戶——角色是用戶定義角色還是固定角色并不重要,是服務(wù)器角色還是數(shù)據(jù)庫(kù)角色也沒(méi)什么關(guān)系。無(wú)論在什么情況下,它們的操作幾乎完全一樣。
還要注意的是,所有這些工作都可以在Management Studio中進(jìn)行。要更改與角色相關(guān)聯(lián)的權(quán)限,只需單擊數(shù)據(jù)庫(kù)結(jié)點(diǎn)的角色成員,然后使用復(fù)選框指派權(quán)限即可。當(dāng)想要向角色中添加用戶時(shí),只需去到用戶的屬性對(duì)話框中,選擇服務(wù)器或數(shù)據(jù)庫(kù)角色選項(xiàng)卡,然后,在所有想要用戶擁有其角色成員身份的角色上打上勾號(hào)。
● 刪除角色
刪除角色與添加角色一樣容易。其語(yǔ)法很簡(jiǎn)單:
EXEC sp_droprole <'角色名'>
執(zhí)行后,角色就被刪除了。