【譯】第三篇 SQL Server安全主體和安全對象


本篇文章是SQL Server安全系列的第三篇,詳細內容請參考原文


一般來說,你通過給主體分配對象的權限來實現SQL Server上的用戶與對象的安全。在這一系列,你會學習在SQL Server實例中通過權限授權來執行操作及訪問安全對象。在SQL Server中重要的主體是角色,你會學習角色可以讓安全管理比使用單獨用戶更容易。你也會學習SQL Server的安全對象。
授權(Authorization)
Authentication is only part of accessing all of the goodies in a database server。認證(Authentication)有點像是有一個護照證明你是誰,但沒有簽證。你需要一個簽證才能訪問其他國家。在這一篇你會學習授權以及它是如何作為簽證訪問數據庫對象。
主體是一個用戶或進程可以訪問一個或多個SQL Server/數據庫的安全對象。一個安全對象是一個受保護的資源,只有某些人或過程可以查看或更改,比如一個表中的數據。一個權限使主體獲得訪問一種特定類型安全對象。
繼續護照的比喻,主體是護照的持有人,安全對象是主體想訪問的國家,權限是簽證可以跨越國界並享有訪問。
主體(Principals)
主體,在安全上下文是任何用戶、組(SQL Server中稱作角色)、或進程中運行的代碼,可以請求訪問安全對象並且被授予或拒絕訪問。所有的Windows和SQL Server登錄名都是主體,以及它們映射到數據庫中的用戶。下面的列表顯示了大多數SQL Server中重要主體的層次,從服務器級到SQL Server實例級,再到數據庫級的主體。
Windows級主體
->Windows域登錄
->Windows組
->Windows本地登錄
SQL Server級主體
->SQL Server登錄
->SQL Server登錄映射到證書
->SQL Server登錄映射到Windows登錄
->SQL Server登錄映射到非對稱密鑰
數據庫級主體
->應用程序角色
->數據庫角色
->數據庫用戶
->數據庫用戶映射到證書
->數據庫用戶映射到Windows登錄
->數據庫用戶映射到非對稱密鑰
->Public角色
重要的是要理解這個層次,因為一個主體的范圍決定了授予它的權限的范圍。例如,數據庫用戶只有在授予權限的數據庫中有權限。一個SQL Server級別的主體可以在SQL Server上有權限,而Windows級別的主體有權限超出SQL Server的限制,在Windows的本地實例和整個網絡。
一個主體可以是一個登錄(或用戶)或是角色。在SQL Server角色的作用類似於Windows組。角色中的成員繼承分配給角色的權限。角色使安全管理更容易,因為你不需要為單獨的用戶管理復雜的權限。SQL Server支持以下類型的角色:
->固定服務器角色:SQL Server內置角色執行服務器級任務
->用戶定義的服務器角色:你創建的自定義服務器角色,分配服務器級權限,並指定登錄名,以便登錄名繼承服務器對象的權限
->固定數據庫角色:內置角色執行數據庫任務和分配基本權限
->用戶定義的數據庫角色:你創建的自定義數據庫角色,分配權限,然后添加用戶,以便用戶繼承數據庫對象的權限
你可以將用戶分配給多個角色。角色也可以嵌套,但是如果你的嵌套太復雜,你會受到性能損失,並且它可能會成為維護和診斷的噩夢。
固定服務器角色
固定服務器角色是SQL Server內置的角色,你不能以任何方式改變他們,你只可以給他們添加登錄名。它們存在於服務器級別僅用於執行管理任務。SQL Server中固定服務器角色如下(括號中是實際角色名稱):
->系統管理員(sysadmin):在SQL Server實例執行任何活動。這個角色包含了所有的其他角色,一旦用戶是sysadmin的成員,他們不需要任何其他的角色。sysadmin的成員可以做任何事情,所以很有必要限制成員用戶,只給那些需要並且可以信任的用戶訪問
->大容量插入管理員(bulkadmin):執行BULK INSERT語句讓數據快速導入到數據庫中
->創建數據庫(dbcreator):創建和更改數據庫
->磁盤管理員(diskadmin):管理存儲數據庫的磁盤文件
->進程管理員(processadmin):管理在SQL Server上運行的進程
->服務器管理員(serveradmin):配置服務器范圍的設置。盡管與系統管理員的名稱相似,serveradmin是一個非常不同的和非常有限的角色
->設置管理員(setupadmin):安裝復制和管理擴展程序
->安全管理員(securityadmin):管理服務器的登錄名
固定服務器角色提供的靈活性和安全性允許你將服務器的任務划分成部分。換句話說,如果他們只需要創建數據庫,你就不必讓他們成為系統管理員的成員。讓他們成為dbcreator成員,就有他們需要的所有權限。
你可以使用Management Studio或T-SQL來指定一個登錄名到一個固定服務器角色。要使用Management Studio,執行以下步驟:
1、展開,SSMS>對象資源管理器>安全性>登錄名
2、右鍵單擊Topaz登錄名並從彈出菜單中選擇“屬性”
3、在“登錄屬性”對話框中,選擇“服務器角色”。這將列出所有可用的服務器角色。注意Topaz,像所有的登錄名一樣,已經是public角色的成員
4、指定登錄到dbcreator和diskadmin角色。圖3.1顯示Topaz登錄對話框

圖3.1 分配Topaz登錄名到dbcreator和diskadmin固定服務器角色
5、單擊“確定”以保存更改
或者,你也可以通過對象資源管理器>安全性>服務器角色,來添加登錄名到對應的角色。下面添加Topaz到securityadmin服務器角色:
1、展開,對象資源管理器>安全性>服務器角色
2、右鍵單擊securityadmin服務器角色並選擇屬性,這將打開服務器角色屬性窗口
3、單擊對話框的右下方“添加”按鈕,打開“選擇服務器登錄名或角色”對話框。你可以鍵入Topaz,單擊檢查名稱,或單擊“瀏覽”按鈕來獲得一個登錄名列表。一旦你鍵入Topaz,對話框如圖3.2所示

圖3.2 選擇Topaz添加到服務器角色
4、單擊確定添加Topaz到服務器角色。服務器角色屬性對話框看起來像圖3.3

圖3.3 添加Topaz到securityadmin服務器角色
5、單擊“確定”以保存更改
另一種添加一個登錄名到服務器角色的方式是T-SQL,利用sp_addsrvrolemember系統存儲過程。下面的代碼添加到現有的已有的登錄名Topaz到sysadmin角色:

EXEC sp_addsrvrolemember 'Topaz', 'sysadmin';

代碼3.1 添加登錄名到服務器角色
你可以通過運行sp_helpsrvrole和sp_helpsrvrolemember存儲過程找到有關固定服務器角色信息。如果你給sp_helpsrvrole傳入一個有效的服務器角色名稱,它將顯示該角色的描述;否則顯示所有服務器角色。圖3.4顯示了這兩個過程的使用方式及返回效果。

圖3.4 使用系統存儲過程獲取服務器角色信息
用戶定義的服務器角色
SQL Server 2012中一個期待已久的安全功能是用戶定義的服務器角色。SQL Server很早就有數據庫級別的用戶定義的數據庫角色,但你終於可以得到顆粒與服務器級別權限的自定義服務器角色。
在SQL Server的舊版本,授予用戶的某些權限只能通過分配他們到內置固定服務器角色,這樣通常有太大的權限。讓每個用戶成為系統管理員是一個可怕的但常見的做法,一個特別的問題,因為你不能限制系統管理員什么。This violates the principal of least privilege in a big way, but was often a practical necessity。SQL Server 2005之后,使這一切更精細,讓你指定任何特定的服務器級別的用戶權限,但是缺少將權限放到一個服務器角色里。
SQL Server 2012解決了這個問題,支持用戶定義的服務器角色。使用CREATE SERVER ROLE創建一個新的服務器角色:

CREATE SERVER ROLE LimitedDBA;

代碼3.2 創建服務器角色
你可以授予和拒絕任何想要的服務器級別權限。下面的代碼授予CONTROL SERVER權限給新的角色,然后拒絕部分權限來縮小的服務器角色的成員的權限。這是一個非常靈活的方式授予用戶特定權限。

USE master;
GO
--Grant the role virtual sysadmin permissions
GRANT CONTROL SERVER TO LimitedDBA;
--And take some permissions away
DENY ALTER ANY LOGIN TO LimitedDBA;
DENY ALTER ANY SERVER AUDIT TO LimitedDBA;
--下面兩個注釋的permission_name不存在(08r2)
--DENY ALTER ANY SERVER ROLE TO LimitedDBA;
--DENY CREATE SERVER ROLE TO LimitedDBA;--Covered by ALTER ANY SERVER ROLE
DENY UNSAFE ASSEMBLY TO LimitedDBA;

代碼3.3 給服務器角色授予/拒絕權限
為了測試角色,代碼3.4創建一個映射到Windows組的登錄名,並添加新的登錄名到LimitedDBA角色。

--Create a login for DBAs Windows group
CREATE LOGIN [Marathon\DBAs] FROM WINDOWS;
--Add to the server role
ALTER SERVER ROLE LimitedDBA ADD MEMBER [Marathon\DBAs];

代碼3.4 創建登錄名並添加到服務器角色
代碼3.5中創建一個SQL Server身份驗證的登錄名carol,沒有分配任何SQL Server實例的權限。然后,嘗試在carol安全上下文執行各種操作,這些操作需要服務器級別的權限:創建另一個登錄名、查看系統信息,並創建另一個服務器角色。所有這些操作都失敗了,你可以在圖3.5中看到,因為carol主體沒有任何權限來執行這些操作。

--Create carol login
CREATE LOGIN carol WITH PASSWORD = 'crolPWD123%%%';

EXECUTE AS LOGIN = 'carol';
--Verify user context
PRINT suser_sname();
--Can Carol alter logins?
CREATE LOGIN donkiely WITH PASSWORD = 'G@Sm3aIKU3HA#fW^MNyA';--No
--Other server-level permissions?
SELECT * FROM sys.dm_exec_cached_plans;--No,requires VIEW USER STATE
CREATE SERVER ROLE CarolRole;--No
REVERT;

代碼3.5 創建登錄並測試它是否有特殊權限

圖3.5 執行失敗因為carol沒有權限
接下來的代碼添加carol到LimitedDBA用戶定義服務器角色,並再次嘗試執行相同的操作。如圖3.6所示,現在carol可以獲取系統信息(查詢操作),因為角色授予了CONTROL SERVER權限。但carol仍然無法創建登錄名或服務器角色,因為LimitedDBA角色顯示拒絕了這些權限。

ALTER SERVER ROLE LimitedDBA ADD MEMBER carol;
-- Now does Carol have permissions?
EXECUTE AS LOGIN = 'carol';
CREATE LOGIN donkiely WITH PASSWORD = 'G@Sm3aIKU3HA#fW^MNyA';-- Still not possible
SELECT * FROM sys.dm_exec_cached_plans;-- Yes, CONTROL SERVER covers VIEW USER STATE
CREATE SERVER ROLE CarolRole;-- Not possible
REVERT;

代碼3.6 再次嘗試carol是否有特殊權限

圖3.6 LimitedDBA角色成員執行結果
為了查看你可以授予和拒絕給服務器角色的所有可用的server-level權限,執行以下代碼。圖3.7顯示了結果。

SELECT * FROM sys.fn_builtin_permissions('SERVER') 
 ORDER BY permission_name;

代碼3.7 查看所有可用服務器級別權限

圖3.7 服務器級權限的部分列表
你可以創建用戶定義的服務器角色,根據用戶和組工作需求授予特別的權限,這比早期版本的SQL Server更靈活,使安全管理在SQL Server 2012更容易,更容易的管理必然意味着一個更安全的服務器。
固定數據庫角色
固定數據庫角色存在於數據庫級別,而不是服務器級別,僅在數據庫中控制權限。每個數據庫都有它自己的固定數據庫角色集合,所以你可以單獨配置每個數據庫中的角色。固定數據庫角色類似於固定服務器角色,在這個意義上,它們不能被刪除、修改或更改,但可以添加數據庫用戶和用戶定義的角色。固定數據庫角色有:
->db_accessadmin:可以添加或刪除數據庫中的Windows登錄名和組和SQL Server登錄名。
->db_backupoperator: 可以備份數據庫
->db_datareader:可以查看數據庫中所有用戶表的數據
->db_datawriter: 可以增加、修改或刪除數據庫中所有用戶表的數據
->db_ddladmin:可以在數據庫中添加、修改或刪除對象。(DDL代表數據定義語言,使數據庫結構變化的一組T-SQL命令)
->db_denydatareader:無法查看數據庫中的任何數據
->db_denydatawriter:無法更改數據庫中的任何數據
->db_owner:可以執行所有的數據庫角色以及維護和配置活動。這個角色包含了所有其他的角色,所以它基本上是這個數據庫的管理員
->db_securityadmin:可以在數據庫中管理角色成員、語句和對象權限
固定數據庫角色可以簡化數據庫中的權限分配。例如,假設你希望只允許用戶備份某個特定的數據庫。你不希望用戶能夠讀取數據,只要備份。你能很容易完成這個讓用戶成為db_backupoperator和db_denydatareader角色的成員。使用sp_helprole和sp_helprolemember系統存儲過程來查看有關數據庫角色信息。
The Public Role and Guest User
有一些特別的主體需要注意。你可能不會以任何有意義的方式來使用這些主體,但它們確實會影響安全性,所以你需要知道他們是什么。
Public角色是一種特殊的服務器角色,不能被刪除。每個數據庫用戶都屬於這個Public角色,所以你不需要為它分配用戶、組或角色。每一個SQL Server數據庫中包含Public角色,包括master、msdb、tempdb和model。但是,你可以授予或限制Public角色的權限,根據你的安全需要決定。重要的事情要記住的是,你授予給Public角色的權限,適用於所有的數據庫用戶。
Guest用戶在每個數據庫中都存在,包括系統數據庫。作為用戶,它繼承了Public角色的權限。它是當一個登錄名沒有在數據庫中映射用戶時使用的。默認情況下,Guest用戶沒有權限,但你可以授予訪問數據庫對象的權限,並在數據庫中執行操作。正如你所預期的,這是一個非常危險的事情,在一個良好設計的數據庫服務器是很少需要的,你應該避免分配權限給Guest用戶。雖然你不能刪除Guest用戶,你應該在用戶數據庫中禁用它。

USE Northwind;
GO
REVOKE CONNECT FROM guest;
GO

代碼3.8 通過回收連接權限禁用Guest用戶
注意:不要禁用系統數據庫中的Guest用戶,這可能會導致你不想處理的問題!這些數據庫需要Guest用戶的各種功能。
dbo用戶和架構
dbo是一個特殊的用戶帳戶在每個數據庫映射為sysadmin固定服務器角色。這意味着如果你是sysadmin角色的成員,你創建的任何數據庫對象,對象的所有者會是dbo,而不是你。你不能刪除dbo用戶,它的映射只有sysadmin,而不是數據庫所有者(db_owner)。
每個數據庫有dbo架構,並且是dbo用戶的默認架構。因此,當你以sysadmin訪問一個數據庫,並創建一個對象,而不指定架構,它的兩部分名稱將是dbo.objectname。其他用戶訪問數據時如果沒有指定架構名稱,dbo架構就是它們的第二個默認架構。如果用戶Joe試圖訪問表sales,SQL Server將首先檢查是否有Joe默認架構的sales表,如果沒有,它會檢查是否有dbo.sales。只有在兩種架構下都沒有找到sales表,才會返回錯誤信息。最佳實踐是為每個對象指定一個架構名稱。
用戶定義數據庫角色
數據庫角色並不局限於預定義的角色,你可以創建自己的角色。用戶可以定義類型的數據庫角色:
->標准角色:使用此角色來簡化用戶組的權限。你可以嵌套固定數據庫角色或其他用戶定義的角色,並將用戶分配給角色,在這種情況下,他們繼承了角色的權限。
->應用程序角色:應用程序使用這個角色允許應用程序或連接登錄到數據庫,並通過提供角色名稱和密碼來激活應用程序角色。你不能像其他角色添加用戶的方式將用戶添加到應用程序角色,而且一旦激活,應用程序權限的生命周期存在於連接期間。用戶任何單獨的權限可能置疑,直到檢查應用程序權限。
你可以將用戶定義的數據庫角色添加到固定數據庫角色,類似於將用戶添加到固定數據庫角色,通過固定數據庫角色的屬性窗口。
安全對象
一個安全對象是一個你可以訪問控制的受保護資源。通常它是一個物理的東西,或者至少是一個可以物理化的數字對象。但安全對象也可以是一個操作,可以對數據庫或數據庫實例做出某些改變。例如,一個管理員可以授予一個主體擁有某個對象。授予此權限並不能立即更改該對象的所有者,它只是給主體在未來的時間里有能力去做。
圖3.8顯示了在SQL Server實例的大部分安全對象。服務器級別的安全對象具有最廣泛的范圍,including permissions that affect a principal’s ability to make changes to all databases。數據庫級別范圍包括一個特定的數據庫中的所有對象,比如那些用於管理用戶以及創建加密密鑰的對象。架構范圍包括架構內的所有對象,基本上是數據庫的數據結構,包括表及其數據。數據庫可以包含多種架構,並且每種架構都包含一個完整的數據庫對象集合的子集。架構功能的強大之處,你可以指定和拒絕架構權限,並且這些權限適用於架構包含的所有對象。

圖3.8 SQL Server中的安全對象
注意:授予服務器級別的權限通常會影響到小/低范圍的權限。例如,授予數據庫級權限可能意味着主體對對象在一個或全部數據庫架構中具有隱含權限。
總結
這一篇學習了授權、主體和安全對象。在下一篇你將了解權限,給主體授予或拒絕對對象做某事的能力。通過理解,你就可以有效的利用SQL Server的認證和授權粒度嚴格控制數據庫資源,同時允許授權用戶和進程完成他們的工作。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM