Security 10:權限管理

在進行權限管理時,應遵照「最低權限」原則,即每一個人只授予必需的最小權限。相對於授予的權限,數據庫中還有一個特殊的權限,那就是全部權(Ownship)。sql

SQL Server 用於管理權限的TSQL命令有:GRANT用於授予權限,REVOKE 用於移除已經被GRANT/DENY的權限,而DENY用於防止安全主體經過GRANT得到權限。DENY一旦執行,Principal在Securable上的權限就被禁用了。可是,SQL Server的權限空間不是扁平的,是立體的,在不一樣的安全上下文(Security context)中,不一樣的權限空間(Permission Space)中,這三個命令的優先級是不一樣的。這就意味着,即便執行GRANT授予權限,用戶不必定有權限,這是由於在特定的權限空間裏,Deny命令禁用了用戶的權限,同時Grant命令的優先級低於Deny。數據庫

一,管理權限的規則

在管理權限時,要注意權限的上下文、權限的立體空間和權限的優先級安全

1,安全上下文和權限空間函數

安全上下文(Security Context),是跟user 或 login 相關的環境,用戶能夠經過EXECUTE AS 來切換安全上下文。安全上下文主要包括:Login、User、Role membership、Windows Group membershipurl

權限空間,是指安全對象(Securable)和包含安全對象的全部安全對象類(Securable class),好比,表包含在schema 中,schema是表的安全對象類;而database包含schema,database是schema的安全對象類。訪問表的權限,受到表、schema和database的權限的影響,這三個對象構成一個權限空間,訪問受到權限空間的約束。spa

2,權限的優先級.net

當這三個命令做用於同一個安全對象(Securable)時,狀況會變得複雜,不只須要考慮權限空間,還須要考慮權限的優先級。3d

  • 在同一個安全主體範圍內對同一個安全對象設置權限,GRANT子句會移除DENY和REVOKE子句設置的權限,這三個命令的優先級相同,後執行的語句會移除先執行語句的效果。
  • 可是,當相同的權限做用於同一安全主體的不一樣範圍時,若是DENY 做用於更高的範圍內,那麼DENY優先,可是在更高的範圍內,REVOKE不優先。
  • 這裏有一個例外,列級別的GRANT語句,會覆蓋Object級別的DENY語句,可是後續Object級別的DENY語句會覆蓋列級別的GRANT語句。

權限是累積的,一個User能夠經過多種途徑(好比Grant、Role和Group memberhsip)來得到受權,Revoke只能回收某一個途徑上的權限,可是Deny會禁止用戶得到受權。server

舉個例子,一個User經過Grant得到表1的SELECT權限,經過Role得到表1的SELECT權限:對象

  • 狀況1:當使用REVOKE命令回收GRANT授予的SELECT 權限時,該User仍然能夠經過Role的權限來查詢表1。
  • 狀況2:當使用DENY命令拒絕表1的權限時,該User沒有權限查詢表1。

3,權限的層次結構

權限的層次結構是一種父子結構,擁有父級別對象的權限,默認擁有全部子級別對象的權限。舉個例子,若是有數據庫級別的SELECT權限,那麼就有了數據庫下全部Schema的SELECT權限;若是有Schema的SELECT權限,那麼就有了Schema下全部對象的SELECT權限,這種權限的結構構成權限空間。

權限是一個覆蓋式的權限,舉個例子,Control表示全部的權限,當對一個對象授予Control權限,意味着授予全部其餘的權限。

數據庫級別的權限:

  • 在數據庫級別授予操做數據庫對象的權限,好比 EXECUTE、DELETE、INSERT、SELECT、UPDATE、REFERENCES、VIEW DEFINITION,實際上,授予的是操做數據庫中全部對象的權限。
  • 數據庫級別獨有的權限:ALTER、BACKUP DATABASE、BACKUP LOG、CHECKPOINT、CONNECT、CREATE TABLE、CREATE VIEW、CREATE PROCEDURE等

二,權限管理的實現

權限管理涉及到Principal、Securable和Permission三個概念。Principal能夠是單個User,也能夠是多個User構成的Windows Group;Securable能夠是單個數據庫對象,也能夠是包含多個數據庫對象的schema;同時,User也能夠經過role得到數據庫對象的權限。

第一種方式,爲每個User設置單個Securable的權限

 第二種方式,建立Windows Group,把User分組,爲每個Windows Group設置單個Securable的權限,簡少了受權用戶的數量。

第三種方式,經過數據庫 role來設置權限,經過Role來組織Securable,減小了受權對象的數量。

第四種方式,經過Schema來設置權限,在一個Schema下包含多個Securables,並經過Role來管理Scurable,經過Windows Group來管理User,這種方式雖然複雜,可是權限的管理很是精細和靈活。

三,全部權和全部權鏈

對象的全部者對一個對象擁有全部可能的權限,而且這些權限不能禁止。CONTROL權限能夠執行與對象全部者幾乎相同的操做,可是全部權和受權是不一樣的。對象的全部者一般是其建立者,可是能夠在建立時使用AUTHORIZATION子句指定其餘全部者,也能夠把Ownship轉移給其餘Principal。

如何在不授予基礎表訪問權限的狀況下,僅對視圖或任何其餘類型的程序授予SELECT權限呢?答案是使用全部權鏈(Ownership-chaining)。一般狀況下,當用戶從視圖中查詢數據時,系統作兩次權限檢查,第一次是檢查用戶是否有權限查詢視圖,第二次是在視圖引用基礎表時檢查用戶是否有權限查詢基礎表,因爲用戶沒有基礎表的權限,所以第二次權限檢查失敗。

全部權鏈(Ownership-chaining)經過繞過第二次權限檢查來避免這種狀況,不然將在視圖引用基礎表時進行第二次權限檢查。當連接的對象(underlying table)與調用對象(view)具備相同的全部者時,權限檢查將被徹底繞開。

若是一個user在具備Ownership權限的Schema中建立視圖,由於它視圖的全部者,就是被視圖引用的基表的全部者,這是一個鏈:我是Schema的全部者,那麼Schema下的全部對象的Owner都是我,我有權限訪問視圖,但不能訪問基礎表。

 

全部權鏈只適用於SELECT, INSERT, DELETE, UPDATE 和MERGE,以及 SP和函數的EXECUTE 權限,出於安全考慮,不適用於使用動態SQL的程序中。要在SP、函數和觸發器中執行動態SQL操做,須要使用使用WITH EXECUTE AS子句使用權限模擬。只要調用者對動態SQL中引用的數據庫對象沒有權限,就可使用此EXECUTE AS子句,但要格外當心。它經過將執行上下文切換到模擬用戶來實現。全部代碼,甚至是嵌套模塊,都將在模擬用戶的安全上下文中執行。當前正在執行的批處理在執行代碼時會臨時得到例程全部者的權限,而不是全部者的身份。這樣,用戶只能經過更改正在執行的代碼來將特權用於任何其餘目的。僅在過程執行完成後或在REVERT語句上,執行上下文才還原爲原始調用方。

全部權鏈的問題在於,除了第一次權限檢查以外,全部權連接會徹底繞過權限檢查,甚至都優先於DENY ACCESS。

 

參考文檔:

Getting Started with Database Engine Permissions

Schema-Based Access Control for SQL Server Databases

Permissions (Database Engine)

相關文章
相關標籤/搜索