【譯】第四篇 SQL Server安全權限


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


權限授予主體訪問對象,以執行某些操作。SQL Server有大量你可以授予給主體的權限,你甚至可以拒絕或回收權限。這聽起來有點復雜,但在這一系列,你將知道SQL Server權限是如何工作的,你可以非常精細地在數據庫和服務器對象上控制對象創建、數據訪問、以及其他類型操作。
權限
權限像一個簽證允許你訪問外國,通常有一些基本條件。比如,你只有六個月的期限,你被限制在3/7的地區旅行。類似的,SQL Server權限給主體訪問數據庫對象做一些事或執行操作。權限可以允許主體讀取表的數據或表的某一部分,或能夠運行一段特定的代碼。甚至允許主體給其他登錄名授予權限。你可以給不同的主體授予數百種不同的權限。
在授予權限時,你要遵循最小特權原則。最小特權意味着,你給一個主體需要完成一個任務的權限——沒有多也沒有少。堅持最小特權原則,是數據庫安全的重要步驟。如果主體在數據庫中唯一能做的事情是讀取產品信息,這個主體就不應該能有意或無意刪除表中的內容。本質上是建立一個嚴密的容器限制主體可以做什么。
權限類型
SQL Server有許多種你可以授予主體控制訪問安全對象的權限。下面列出最常見的權限:
控制:賦予安全對象的所有可能的權限,使主體成為安全對象的虛擬擁有者。這包括將安全對象授予權限給其他主體。
創建:賦予創建一個特定對象的能力,這取決於它被授予的范圍。例如,CREATE DATABASE權限允許主體在SQL Server實例創建新的數據庫。
更改:賦予更改安全對象屬性的權限,除了更改所有者。這個權限包含了同范圍的alter、create、drop對象的權限(比如,用戶對表A有更改權限,那么它能夠add/alter/drop列、create/drop索引約束等)例如,一個數據庫級別的更改權限,包括更改表和架構權限。
刪除:允許一個主體刪除任何或所有存儲在表中的數據。是一個非常危險的權限!
模擬<登錄>或者模擬<用戶名>:賦予主體模擬另一個登錄/用戶。通常用於改變存儲過程的執行上下文。
插入:允許主體往表中插入新記錄
選擇:授予主體從一個特定的表讀取數據。這是用戶需要的最常見的權限,以便他們可以在表上執行查詢。
接管所有權:Confers on a principal permission to take ownership of an object. Granting this permission does not immediately transfer ownership. Instead, it allows the principal to take ownership at some future time.
更新:允許主體更新表中的數據。
查看定義:賦予主體權限查看安全對象的定義。這是一個重要的權限,因為結構信息在數據庫攻擊中是非常有用的。如果沒有這個權限,攻擊者發現數據庫或服務器實例有價值目標的能力將嚴重受限。
創建和更改權限可以使用ANY關鍵字:CREATE ANY <object type> and ALTER ANY <object type>.這些權限授予創建或更改任何指定類型安全對象。例如,在數據庫級別上授予ALTER ANY SCHEMA,允許改變數據庫中任何架構的屬性。在服務器級別上,ALTER ANY LOGIN允許主體改變服務器上任何登錄名。使用ANY關鍵字,可以靈活的讓主體創建或修改一整類的對象,而不是一個單一的對象。只是要注意,在創建和修改權限之間有一些細微的差別。
當你考慮在SQL Server安全對象的數量和一個對象可以擁有潛在權限類型的數量時,你開始意識到有顆粒的權限。你可以應用最小特權原則來實現任何用戶或角色的權限集,通過給予用戶恰當的權限來完成一項任務,而不需要將其他對象暴露。
提示:如果你使用SQL Server早期版本,你會意識到,SQL Server 2005及之后版本完全修改了可用的權限。你不必再將一個用戶分配給一個可能有幾十個不必要的權限的角色,從而違反了最小特權,並將數據庫暴露在有意或偶然的濫用。
這里一個主要考慮是,授予一個權限不一定有效地授予執行一項操作的能力。有時還需要其他權限,提供一個全面的安全上下文來執行敏感操作的能力。一個很常見的例子是創建表權限。授予這個權限,理論上允許一個主體在特定的數據庫下創建表。但主體還需要有能力在一個架構中創建表。如果主體沒有對任何架構的更改權限,它將無法創建一個表。
權限語句
即使你是通過圖形化工具分配權限,底層還是執行TSQL權限語句。
GRANT:授予對安全對象或操作的權限給主體
REVOKE:“Un-grant”權限,取消一個早期做的grant語句。撤銷的權限仍然可以通過在具有權限的組或角色中繼承。當你創建新的對象時,revoke是默認的權限狀態,所以特定權限沒有授予,但是可以繼承。
DENY:拒絕撤銷權限,使它不能被繼承。這是最具限制性的權限,並且優先於所有其他權限。DENY不適用於sysadmin角色的成員或對象的所有者。
不要低估DENY權限的重要性。例如,假設你有一個臨時雇員,他是進來做數據輸入,你不希望他能夠編輯或刪除現有記錄。你已經分配給editor角色(公司內部人員都屬於)對某些表的足夠的權限。你可以創建一個特殊的登錄名,然后在適當的表上deny UPDATE和DELETE權限。臨時雇員可以從editor角色繼承足夠的權限輸入新記錄,但是不能修改/刪除已存在的記錄。
授予權限
在Management Studio下授予權限的最靈活的方法是修改數據庫用戶或角色的屬性。你還可以通過修改單個對象的屬性來授予權限,但這種方法不靈活,並且具有更高的維護成本。
下面的練習將在AdventureWorks2012數據庫創建自定義數據庫角色。這個角色的成員,需要必要的權限插入和更新一些HR相關的表,並且能夠執行相關的存儲過程,但沒有其他的特殊權限。
提示:一旦你為一個用戶配置權限,然后需要為另一個用戶重復上述過程,授予和第一個用戶同樣的權限,那么把權限分配給一個角色,然后簡單地將用戶添加到角色即可。
你可以利用第二篇在AdventureWorks2012數據庫下創建的用戶Topaz。如果你沒有創建用戶,執行代碼4.1創建登錄名和用戶。

USE master;
GO
CREATE LOGIN Topaz WITH PASSWORD = 'yBqyZIPT8}b]b[{5al0v';
GO
USE AdventureWorks2012;
GO
CREATE USER Topaz FOR LOGIN Topaz
    WITH DEFAULT_SCHEMA = HumanResources;
GO
View Code

代碼4.1 創建創建名並映射到數據庫用戶
在AdventureWorks2012數據庫創建一個DataEntry自定義數據庫角色,參考如下步驟:
1、SSMS連接到安裝有AdventureWorks2012數據庫的實例。對象資源管理器->數據庫->AdventureWorks2012->安全性->角色->數據庫角色
2、右擊數據庫角色,彈出菜單選擇新建數據庫角色
3、角色名稱鍵入DataEntry,所有者dbo
4、點擊添加按鈕,將用戶Topaz添加到角色(如果用戶不存在請先創建)。在你關閉選擇數據庫用戶或角色對話框后,數據庫角色-新建對話框應該如圖4.1所示

圖4.1 創建DataEntry數據庫角色並添加Topaz用戶
5、點擊確定保存修改並創建角色
當前DataEntry角色並不允許角色中的成員能做什么,因為你還沒有給角色分配任何權限。DataEntry角色中的成員需要能夠往表Employee、Address、JobCandidate插入和更新數據,同時他們需要執行uspUpdateEmployeeHireInfo和uspUpdateEmployeePersonaInfo存儲過程。但是他們不能查看存儲過程的定義。
使用下面的步驟給DataEntry角色添加合適的權限
1、對象資源管理器->數據庫->AdventureWorks2012->安全性->角色->數據庫角色->DataEntry
2、右擊DataEntry,彈出菜單選擇屬性。打開數據庫角色屬性對話框
3、左側選擇安全對象,這個頁面讓你選擇角色有權操作的安全對象,並指定對安全對象上的權限
4、點擊“搜索”按鈕添加安全對象。這將打開“添加對象”對話框,該對話框提供了特定對象、特定類型的所有對象、屬於該架構的所有對象的選項。在本例中,因為你想為表和存儲過程中添加權限,圖4.2中保持默認選擇-特定對象,然后單擊“確定”

圖4.2 選擇添加對象
5、打開“選擇對象”對話框。單擊“對象類型”按鈕打開“選擇對象類型”對話框,然后從列表中選擇“存儲過程”和“表”,如圖4.3所示。請單擊“確定”以關閉該對話框並返回“選擇對象”對話框,該對話框現在看起來像圖4.4。你將看到在對象類型框中列出的存儲過程和表

圖4.3 選擇對象類型

圖4.4 選擇對象
6、單擊“瀏覽”按鈕以查看數據庫中的存儲過程和表的列表。這將打開“查找對象”對話框,向下滾動查找並選擇對象。

圖4.5 選擇存儲過程和表
7、單擊“確定”以關閉“查找對象”對話框中。此時你選擇的對象以分號分隔列在選擇對象對話框中,如圖4.6所示。請單擊“確定”以關閉該對話框並保存更改

圖4.6 選擇對象結果
8、現在DataEntry數據庫角色屬性對話框列出你選擇的安全對象,並且列出每個對象可用的權限。DataEntry角色成員需要可以插入和更新數據到這些表,逐一選擇表,在對話框的下部勾選插入/更新授予列的復選框。圖4.7顯示了HumanResources.Employee表的權限

圖4.7 在表上授予插入/更新權限
提示:授予(Grant)允許指定的權限,具有授予權限(With Grant)允許用戶或角色授予其他主體的權限。小心With Grant權限!
9、對於每一個存儲過程,授予執行權限並拒絕查看定義權限。圖4.8顯示了useUpdateEmployeeHireInfo存儲過程的權限

圖4.8 授予執行過程權限、拒絕查看定義權限
10、在“數據庫角色屬性”對話框中單擊“確定”以保存你的更改並提交到數據庫。根據選定的對象和權限的數量,這可能需要一些時間。
當然,你可以使用T-SQL代碼創建對象並分配權限。代碼4.2創建DataEntry角色,添加Topaz用戶,然后分配和圖形界面相同的權限。

-- Create the DataEntry role and assign Topaz to it
CREATE ROLE [DataEntry] AUTHORIZATION [dbo];
ALTER ROLE [DataEntry] ADD MEMBER [Topaz];
-- Assign permissions to the DataEntry role
GRANT INSERT ON [HumanResources].[Employee] TO [DataEntry];
GRANT UPDATE ON [HumanResources].[Employee] TO [DataEntry];
GRANT INSERT ON [HumanResources].[JobCandidate] TO [DataEntry];
GRANT UPDATE ON [HumanResources].[JobCandidate] TO [DataEntry];
GRANT INSERT ON [Person].[Address] TO [DataEntry];
GRANT UPDATE ON [Person].[Address] TO [DataEntry];
GRANT EXECUTE ON [HumanResources].[uspUpdateEmployeeHireInfo] TO [DataEntry];
DENY VIEW DEFINITION ON [HumanResources].[uspUpdateEmployeeHireInfo] TO [DataEntry];
GRANT EXECUTE ON [HumanResources].[uspUpdateEmployeePersonalInfo] TO [DataEntry]
DENY VIEW DEFINITION ON [HumanResources].[uspUpdateEmployeePersonalInfo] TO [DataEntry];
GO

代碼4.2 語句創建角色並分配權限
檢查和測試權限
如果你想檢查DataEntry角色的權限,你可以使用GUI工具或執行T-SQL代碼訪問數據庫對象的元數據。使用GUI,對象資源管理器->數據庫->AdventureWorks2012->安全性->角色->數據庫角色->DataEntry->屬性。這將打開和創建角色相同的"數據庫角色屬性"對話框,你可以使用安全對象審查該角色的權限。
或者你可以使用代碼4.3中的T-SQL查看DataEntry角色的權限,利用sys.database_permissions和sys.database_principals安全目錄視圖和sys.objects目錄視圖。

SELECT DB_NAME() AS 'Database', p.name, p.type_desc, dbp.state_desc, 
    dbp.permission_name, so.name, so.type_desc
FROM sys.database_permissions dbp 
    LEFT JOIN sys.objects so ON dbp.major_id = so.object_id 
    LEFT JOIN sys.database_principals p ON dbp.grantee_principal_id = p.principal_id 
WHERE p.name = 'DataEntry'
ORDER BY so.name, dbp.permission_name;

代碼4.3 查看DataEntry角色的權限
當你執行上面代碼,你將會看到結果如圖4.9所示

圖4.9 DataEntry角色的權限
你可以通過打開新建查詢->更改連接用Topaz登錄測試這些權限。然后嘗試在HumanResources.Employee、HumanResources.JobCandidate、Person.Address表插入新行或更新已有數據,並執行分配權限的存儲過程。這些操作應該成功。然后嘗試插入或更新其他表中的數據,這些操作應該失敗。你應該只能夠執行已經授予的權限。
你可以用代碼4.4執行相同的測試。代碼開始設置的執行上下文為Topaz,DataEntry角色的成員。然后插入新行到Person.Address表。這一操作成功,因為角色允許在Person.Address表插入數據。然后代碼試圖插入新行到HumanResources.Department表,插入失敗,因為角色在此表沒有insert權限。接下來的代碼成功執行HumanResources.uspUpdateEmployeePersonalInfo存儲過程;執行dbo.uspGetManagerEmployees失敗,因為角色沒有此過程執行權限。最后,代碼將執行上下文切回到登錄時的安全上下文。

EXECUTE AS USER = 'Topaz';
-- Succeeds
INSERT INTO Person.Address
    (AddressLine1, City, StateProvinceID, PostalCode)
VALUES
    ('8 Hazelnut', 'Irvine', 9, '92602');
GO
-- Fails
INSERT INTO HumanResources.Department
    (Name, GroupName)
VALUES
    ('Advertising', 'Sales and Marketing');
GO
-- Succeeds (doesn't actually change any data)
DECLARE @RC INT;
EXECUTE @RC = HumanResources.uspUpdateEmployeePersonalInfo 
   1, '295847284', '1963-03-02', 'S', 'M';
GO
-- Fails
EXECUTE dbo.uspGetManagerEmployees 1;
GO
REVERT;

代碼4.4 測試DataEntry角色的權限
總結
The ability to assign granular permissions on securable objects throughout SQL Server to various types of principals gives you very fine control over the security of a SQL Server instance.它讓你充分利用最小特權的安全原則,能夠限制主體執行操作和訪問數據的能力到他們需要的最低限度。


免責聲明!

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



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