SQL Server 權限管理


標簽:SQL SERVER/MSSQL SERVER/數據庫/DBA/權限控制/管理/分配/登入名/數據庫用戶/角色

概述

      對數據庫系統而言,保證數據的安全性永遠都是最重要的問題之一。一個好的數據庫環境,必須明確每個用戶的職責,並分配其對應的權限。同時出現問題了也可以找到根源。

你是否會有這樣的需求:

  1. 給某個用戶查詢所有數據庫的權限
  2. 給某個用戶只有備份數據庫的權限
  3. 給一個用戶只有指定數據庫的權限
  4. 給一個用戶只有某個表的權限
  5. 給一個用戶只有查看某些對象(例如:視圖)的權限
  6. 給一個用戶只有執行一些存儲過程的權限

 

目錄

元素

文章可能會有些枯燥,還望耐心,相信應該有你想要的。

登入名

只有擁有了登入名才能訪問實例(sql server).

角色

角色是一類權限的組合。

  • 數據庫角色的擁有者可以是用戶也可以是數據庫角色本身,管理員可以創建數據庫角色,也可以勉強將數據庫角色理解為一組相同權限的用戶,為什么這么說呢,因為數據庫角色和數據庫用戶不允許存在同名。

注意:不要將用戶創建的數據庫角色添加到固定的服務器數據庫角色當中去,否則將導致固定的數據庫角色的權限升級。

  • 服務器角色的擁有者只有登入名,服務器角色是固定的,用戶無法創建服務器角色。

注意:一般不建議給用戶直接分配服務器角色,因為服務器角色是全局的,也就是說你擁有了服務器級別的權限,一般建議給用戶分配數據庫,然后給對應的數據庫分配數據庫角色權限。

用戶

      用戶是數據庫級的概念,數據庫用戶必須綁定具體的登入名,你也可以在新建登入名的時候綁定此登入名擁有的數據庫,當你綁定登入名數據庫后,數據庫默認就創建了此登入名同名的數據庫用戶,登入名與數據庫用戶之間就存在關聯關系,數據庫用戶是架構和數據庫角色的擁有者,即你可以將某個架構分配給用戶那么該用戶就擁有了該架構所包含的對象,你也可以將某個數據庫角色分配給用戶,此用戶就擁有該數據庫角色的權限。

架構

      架構是對象的擁有者,架構本身無權限,架構包含數據庫對象:如表、視圖、存儲過程和函數等,平時最常見的默認架構dbo.,如果沒指定架構默認創建數據庫對象都是以dbo.開頭,架構的擁有者是數據庫用戶、數據庫角色、應用程序角色。用戶創建的架構和角色只能作用於當前庫。

 

 理解了這些概念之后接下來就可以實踐了,接下來我們測試的都是服務器角色選擇public,只測試對數據庫權限的控制。

權限分配

新建登入名

新建一個登入名person,只給登入名服務器角色分配public權限,不分配數據庫

接下來用person登入實例,person用戶無法訪問任何數據庫,由於我們未給用戶分配任何數據庫。

給用戶分配數據庫查看權限

只允許用戶查看AdventureWorks2008R2數據庫

 此時用戶可以查詢所有對象,但無法修改對象。

給用戶查詢某個對象的權限

      如果覺得給用戶查看權限太大了,將da_datareader數據庫角色權限回收,你會發現用戶可以訪問數據庫,但是看不到任何對象。

   

 只給用戶查看Person.Address表

USE AdventureWorks2008R2;
GRANT SELECT ON OBJECT::Person.Address TO person;
--或者使用
USE AdventureWorks2008R2;
GRANT SELECT ON Person.Address TO RosaQdM;
GO

擴展功能

--以下都是賦予用戶對表的dml權限
---授予用戶person對表Person.Address的修改權限
USE AdventureWorks2008R2;
GRANT UPDATE ON Person.Address TO person;
GO

---授予用戶person對表Person.Address的插入權限
USE AdventureWorks2008R2;
GRANT INSERT ON Person.Address TO person;
GO

---授予用戶person對表Person.Address的刪除權限
USE AdventureWorks2008R2;
GRANT DELETE ON Person.Address TO person;

 --授予用戶存儲過程dbo.prc_errorlog的執行權限
GRANT EXECUTE ON dbo.prc_errorlog TO person

標量函數權限:EXECUTE、REFERENCES。

表值函數權限:DELETE、INSERT、REFERENCES、SELECT、UPDATE。

存儲過程權限:EXECUTE。

表權限:DELETE、INSERT、REFERENCES、SELECT、UPDATE。

視圖權限:DELETE、INSERT、REFERENCES、SELECT、UPDATE。

授予用戶架構的權限

新建數據庫角色db_persons

新增架構

數據庫-安全性-架構

架構包含數據庫對象

創建架構persons表

---創建架構persons的表
CREATE TABLE Persons.sutdent
(id int not null)

你會發現用戶同時有了Persons.sutdent表的查看權限,因為用戶是數據庫角色db_person的所有者,而db_person又是架構persons的所有者。

創建一些persons架構的視圖,存儲過程

---創建視圖
USE AdventureWorks2008R2
GO
CREATE VIEW Persons.vwsutdent
AS
SELECT * FROM Persons.sutdent

GO
USE AdventureWorks2008R2
GO
---創建存儲過程
CREATE PROCEDURE Persons.SP_sutdent
(@OPTION NVARCHAR(50))
AS
BEGIN
    SET NOCOUNT ON
    IF @OPTION='Select'
    BEGIN
    SELECT * FROM Persons.sutdent
    END
END
 

 

詳細的GRANT功能可以查詢2008r2連接叢書:

ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-CHS/s10de_6tsql/html/a760c16a-4d2d-43f2-be81-ae9315f38185.htm

查詢權限

 

  ---登入名表
  select * from master.sys.syslogins 
  ---登入名與服務器角色關聯表
  select * from sys.server_role_members
  ---服務器角色表
  select * from sys.server_principals
  ----查詢登入名擁有的服務器角色
  select SrvRole = g.name, MemberName = u.name, MemberSID = u.sid
  from sys.server_role_members m  inner join sys.server_principals g on  g.principal_id = m.role_principal_id 
  inner join sys.server_principals u on u.principal_id = m.member_principal_id

  ---數據庫用戶表
  select * from sysusers
  ---數據庫用戶表角色關聯表
  select * from sysmembers 
  ---數據庫角色表
  select * from sys.database_principals
  ----查詢數據庫用戶擁有的角色
  select ta.name as username,tc.name as databaserole  from sysusers ta inner join sysmembers tb on ta.uid=tb.memberuid
  inner join  sys.database_principals tc on tb.groupuid=tc.principal_id  
  

 

查詢登入名與數據庫用戶之間的關系

--查詢當前數據庫用戶關聯的登入名
  use AdventureWorks2008R2
  select ta.name as loginname,tb.name as databaseusername from master.sys.syslogins ta inner join sysusers tb on ta.sid=tb.sid 
  
  /*如果將當前數據庫還原到另一台服務器實例上,剛好那台服務器上也存在person登入用戶,你會發現二者的sid不一樣,
  由於sid不一樣,所以登入用戶不具有當前數據庫的訪問權限,我們要想辦法將二者關聯起來。
  */
  ---關聯登入名與數據庫用戶(將數據庫用戶的sid刷成登入名的sid)
    use AdventureWorks2008R2
    EXEC sp_change_users_login 'Update_One', 'person', 'person'
    Go

查詢數據庫用戶被授予的權限

exec sp_helprotect @username = 'person'

 查詢person數據庫用戶權限會發現,數據庫用戶擁有的權限都是前面使用GRANT賦予的權限,而后面給用戶分配的架構對象不在這個里面顯示,上面顯示的只是被授予的權限,而架構是數據庫用戶所擁有的權限。

 

回收權限

 如果安全對象是數據庫,對應 BACKUP DATABASE、BACKUP LOG、CREATE DATABASE、CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE TABLE 和 CREATE VIEW。

如果安全對象是標量函數,對應 EXECUTE 和 REFERENCES。

如果安全對象是表值函數,對應 DELETE、INSERT、REFERENCES、SELECT 和 UPDATE。

如果安全對象是存儲過程,表示 EXECUTE。

如果安全對象是表,對應 DELETE、INSERT、REFERENCES、SELECT 和 UPDATE。

如果安全對象是視圖, 對應 DELETE、INSERT、REFERENCES、SELECT 和 UPDATE。

 

回收dbo.prc_errorlog存儲過程的執行權限

USE AdventureWorks2008R2;
REVOKE EXECUTE ON dbo.prc_errorlog    FROM person;

回收Person.Address表的查詢,修改,刪除權限

--回收修改
USE AdventureWorks2008R2;
REVOKE update ON   Person.Address FROM person;

USE AdventureWorks2008R2;
REVOKE alter ON   Person.Address FROM person;

--回收刪除
USE AdventureWorks2008R2;
REVOKE delete ON   Person.Address FROM person;

--回收查詢
USE AdventureWorks2008R2;
REVOKE select ON   Person.Address FROM person;

 

 最后剩下owner為‘.’的是數據庫級的權限

最后回收數據庫的權限

USE AdventureWorks2008R2;
REVOKE CREATE TABLE FROM person;
GO

CONNECT權限是用戶訪問數據庫的權限,將此權限回收后用戶將無法訪問數據庫 --USE AdventureWorks2008R2; --REVOKE CONNECT FROM person; --GO

再執行exec sp_helprotect @username = 'person',就剩下action=connect的數據庫訪問權限

將權限回收后,數據庫用戶還剩下架構Persons的權限,如果還需要將該權限回收,只需要用戶取消關聯對應的db_person數據庫角色權限。

 詳細的revoke權限回收請參考2008r2聯機叢書:

ms-help://MS.SQLCC.v10/MS.SQLSVR.v10.zh-CHS/s10de_6tsql/html/9d31d3e7-0883-45cd-bf0e-f0361bbb0956.htm

補充

針對生產數據庫服務器創建一個應用程序訪問的用戶最常見的是授予用戶某個數據庫:“查詢”、“刪除”、“修改”、“插入”、“執行”的權限,用SQL語句實現如下(用戶:person,數據庫:news):
USE [master]
GO
---創建登入名
CREATE LOGIN [person] WITH PASSWORD=N'person', DEFAULT_DATABASE=[news], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
USE [news]
GO
---在指定的數據庫下創建和登入名相關聯的數據庫用戶
CREATE USER [person] FOR LOGIN [person]
GO
USE [news]
GO
---在指定的數據庫下授予用戶SELECT,DELETE,UPDATE,INSERT,EXECUTE權限。
GRANT SELECT,DELETE,UPDATE,INSERT,EXECUTE TO person;

注意:創建登入名在master數據庫下,創建數據庫用戶和授予數據庫權限都是在具體的數據庫下操作。

其它相關權限授予

---授予Profile權限
USE master
GO
GRANT ALTER TRACE TO person
GO
---授予活動監視器權限
USE master
GO
GRANT VIEW SERVER STATE TO person
GO

 

總結

      所以如果你想對某個用戶某個數據庫的權限進行細分,你可以通過GRANT來授予具體的對象給用戶(當然你也可以revoke回收權限),也可以通過添加某個架構的權限給用戶那么用戶就擁有該類架構的權限。 

用戶擁有什么權限取決於角色,而擁有哪些對象取決於擁有包含這些對象的架構,架構的擁有者可以是數據庫用戶也可以是數據庫角色也可以是應用程序角色,明白了這個道理你對權限的管理也就很清晰了。

 雖然心有余但是還是無法將整個知識點給講透,寫文章之前雖然把整個框架給整理了,但是在寫的過程中發現要寫的內容太多了,比如GRANT權限里面就涉及了表、數據庫、應用程序角色、函數、證書、角色、架構、存儲過程、同義詞還有很多;同時表有可以精確到給具體的某個字段的權限,所以太多了,接下來的REVOKE也同樣是這么多。本文可以起到一個引領的作用,讓你了解有這些功能,了解權限的功能細分;如果有興趣的朋友可以更深入的去鑽研,這篇文章寫下來還是挺累的,寫完這篇文章看一下時間已經是凌晨二點鍾,主要是思維不想被中斷所以一口氣給寫完了,希望能給大家有所幫助。

 

 

備注:

    作者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須注明文章來源,且在文章開頭明顯處給明鏈接,否則保留追究責任的權利。

《歡迎交流討論》


免責聲明!

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



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