191.數據安全性控制

第12章數據的安全性控制sql

•    12.1 SQL Server 2014安全體系結構數據庫

•    12.2 角色安全

•    12.3 服務器級的安全控制服務器

•    12.4 數據庫級的安全控制antd

•    12.5 架構級的安全控制架構

 

Ø  SQL Server 2014安全體系結構主要由三部分組成:主體、權限和安全對象。要對安全對象執行某操做,主體必須得到對該對象的操做權限,不然SQL Server將禁止這種操做。主體、權限和安全對象之間的關係可示意如圖12.1所示。app

 

12.1.1 主體函數

        主體是能夠請求SQL Server資源的實體,它其實是擁有必定權限的特定的數據庫對象。每一個主體都具備一個惟一的安全標識符(SID)。按影響範圍的不一樣,主體能夠分爲Windows級主體、服務器級主體和數據庫級主體。post

1. Windows級主體測試

Ø Windows級主體包括Windows域登陸名和Windows本地登陸名。此類主體只限於服務器級操做,而不能將其餘安全對象的操做權限授予給此類主體。在Windows認證模式下使用的就是這種Windows級主體。

 

 

2. 服務器級主體

Ø 服務器級主體包括SQL Server登陸名以及服務器角色。

Ø SQL Server sa登陸名是具備最大權限的服務器級主體。默認狀況下,該登陸名是在安裝實例時建立的。在SQL Server 2014中,sa的默認數據庫爲master。利用sa登陸名能夠建立其餘的SQL Server登陸名,具備相應權限的主體也能夠建立其餘登陸名,從而能夠造成多級別、多層次的服務器主體體系。

Ø 服務器角色是一組服務器級的操做權限的集合,其做用域爲服務器範圍。服務器角色是「固定」在SQL Server中,用戶對其不能建立或刪除,於是也稱爲「固定服務器角色」。

Ø 角色是若干種權限的集合。當將一種角色賦給某一個主體時,該主體即享有該角色包含的全部權限。不難發現,角色的主要做用是簡化權限的管理。「角色」相似於Microsoft Windows操做系統中的「組」。

Ø 表12.1列出了服務器級角色及其對應的操做權限說明。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    注:public也是一種數據庫角色,同時也視爲一種服務器角色。每一個SQL Server登陸名都屬於public服務器角色。若是未向某個服務器主體授予或拒絕對某個安全對象的特定權限,該用戶將繼承授予該對象的public角色的權限。

 

3. 數據庫級主體

Ø 數據庫級主體包括數據庫用戶、數據角色和應用程序角色。

Ø 當建立數據庫時,會默認建立一個名爲guest的數據庫用戶,而且每一個數據庫用戶都自動成爲public角色的成員。

Ø 數據庫角色是一組做用域爲數據庫範圍的若干操做權限的集合。當一個數據庫用戶或數據庫角色成爲某一數據庫角色的成員時,該數據庫用戶或數據庫角色就擁有該數據庫角色的全部操做權限。數據庫角色又能夠分爲固定的數據庫角色和用戶自定義角色。固定的數據庫角色及其權限說明如表12.2所示,用戶自定義角色是由用戶定義的數據庫角色。

 

 

 

    注:角色db_ddladmin包含下列權限:ALTER ANY ASSEMBLY、ALTER ANY ASYMMETRIC KEY、ALTER ANY CERTIFICATE、ALTER ANY CONTRACT、ALTER ANY DATABASE DDL TRIGGER、ALTER ANY DATABASE EVENT、NOTIFICATION、ALTER ANY DATASPACE、ALTER ANY FULLTEXT CATALOG、ALTER ANY MESSAGE TYPE、ALTER ANY REMOTE SERVICE BINDING、ALTER ANY ROUTE、ALTER ANY SCHEMA、ALTER ANY SERVICE、ALTER ANY SYMMETRIC KEY、CHECKPOINT、CREATE AGGREGATE、CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE QUEUE、CREATE RULE、CREATE SYNONYM、CREATE TABLE、CREATE TYPE、CREATE VIEW、CREATE XML SCHEMA COLLECTION、REFERENCES。

 

    應用程序角色的做用是,只容許經過特定的應用程序鏈接的用戶訪問特定數據。在默認狀況下,應用程序角色不包含任何成員,且是非活動的,這是與數據庫角色的主要區別。

 

 

12.1.2 安全對象

Ø 安全對象是SQL Server數據庫引擎受權系統控制對其進行訪問的資源。狹義上,可將數據庫中可以訪問的數據庫對象視爲安全對象,

Ø  表、視圖、存儲過程等都是安全對象。一個主體只有擁有對一個安全對象的操做權限時才能對其進行相應的操做。對安全對象的操做權限能夠授給一個主體或添加到一個角色中。

Ø 按照做用範圍分類,安全對象能夠分爲服務器級安全對象、數據庫級安全對象和架構級安全對象。

 

 

1. 服務器級安全對象

ü 服務器級安全對象是指做用範圍爲服務器的安全對象,它包括端點、登陸用戶和數據庫。服務器級安全對象的操做權限只能賦給服務器級主體(如SQL Server登陸用戶),而不能賦給數據庫級主體(如數據庫用戶)。

2. 數據庫級安全對象

ü 數據庫級安全對象是指做用範圍爲數據庫的安全對象,它包括用戶、角色、應用程序角色、程序集、消息類型、路由、服務、遠程服務綁定、全文目錄、證書、非對稱密鑰、對稱密鑰、約定、架構等。這些對象的操做權限能夠賦給數據庫級主體(如數據庫用戶等)。

3. 架構級安全對象

ü 架構是自SQL Server 2008開始提供的一種對象管理機制,它是造成單個命名空間的數據庫對象的集合。架構級安全對象是指做用範圍爲架構的安全對象,它包括數據類型、XML架構集合和對象類,其中對象類又包括聚合、約束、函數、過程、隊列、統計信息、同義詞、表、視圖等。

 

 

12.1.3 權限

Ø 權限是指出用戶對特定數據庫對象擁有的操做權力,也能夠將權限理解爲這些操做的集合。若是某一個用戶某一個權限,且該權限包含了某一個操做,則該用戶能夠執行該操做。權限是SQL Server採用的主要安全機制。SQL Server經過授予主體的權限或收回已授予的權限來控制主體對安全對象的操做,從而避免越權非法操做,保證數據庫的安全性。

Ø 表12.3列出了主要的權限類別以及可應用這些權限的安全對象的種類。

 

 

第12章數據的安全性控制

•    12.1 SQL Server 2014安全體系結構

•    12.2 角色

•    12.3 服務器級的安全控制

•    12.4 數據庫級的安全控制

•    12.5 架構級的安全控制

 

        角色是數據安全控制中涉及的一個十分重要的概念。簡單而言,角色是相關操做權限的集合。根據做爲對象的不一樣,角色能夠分爲服務器角色、數據庫角色和應用程序角色等。當咱們將一個主體添加到一個角色中,該主體則擁有該角色所包含的所有權限,從而達到簡化權限管理之目的。咱們也能夠進行角色的建立、查看、修改和刪除等操做。

 

12.2.1 服務器角色

Ø 服務器角色是執行服務器級管理的若干權限的集合。當咱們將有關服務器級主體添加到服務器角色中而使它們成爲服務器角色的成員時,這些主體就擁有了該服務器角色所包含的全部權限。顯然,服務器角色簡化了對服務器級主體的權限管理。但服務器角色已經被SQL Server「固化」了(於是又稱固定服務器角色),用戶不能添加、刪除或修改服務器角色的任何屬性。

 

 

Ø  服務器級角色一共有九種:sysadmin、serveradmin、securityadmin、processadmin、setupadmin、bulkadmin、diskadmin、dbcreator和public。其權限簡要說明以下:

•            sysadmin:系統管理員角色,擁有最大最多權限的服務器角色,利用這些權限能夠完成任何的服務器級操做。通常是系統管理員才能被賦予這樣的角色權限。

•            serveradmin:服務器管理員角色,角色成員具備對服務器進行設置和關閉的權限。

•            securityadmin:安全管理員角色,該角色成員能夠對登陸名及其屬性進行管理,包括授予、拒絕、撤銷服務器級或數據庫級的權限,能夠重置登陸名和密碼等。

•            processadmin:進程管理員角色,該角色成員具備終止SQL Server實例中運行進程的權限。

•            setupadmin:設置管理員角色,該角色成員能夠添加和刪除連接服務器。

•            bulkadmin:該角色成員能夠執行BULK INSERT 語句。

•            diskadmin:磁盤管理角色,該角色具備管理磁盤文件的權限。

•            dbcreator:數據庫建立角色,該角色能夠建立、更改、刪除和還原任何數據庫。

•            public:其角色成員能夠查看任何數據庫。

 

 

12.2.2 數據庫角色

Ø  數據庫角色是數據庫級的相關操做權限的集合。數據庫角色分爲兩類,一類是數據庫建立後自動產生的數據庫角色,用戶不能更改或刪除這些角色,這些角色稱爲固定數據庫角色,能夠用系統存儲過程sp_helpdbfixedrole來查看這類數據庫角色,如圖12.2所示。可見,固定數據庫角色一共有九種。

 

 

Ø  另外一類是用戶根據實際須要而建立起來的數據庫角色,稱爲用戶自定義數據庫角色。在Transact-SQL中,建立自定義數據庫用戶可用CREATE ROLE語句來完成。該語句的語法以下:

CREATE ROLE role_name [ AUTHORIZATION owner_name ]

    其中,role_name表示待建立角色的名稱;owner_name表示將擁有新角色的數據庫用戶或角色的名稱,若是未指定owner_name,則執行CREATE ROLE的用戶將擁有該角色。

 

 

【例12.1】  建立自定義數據庫角色,其擁有者爲數據庫用戶。

Ø 下列代碼建立了自定義數據庫角色MyRole1,該角色爲數據庫MyDatabase的用戶user1所擁有:

USE MyDatabase;

CREATE ROLE MyRole1 AUTHORIZATION user1

     若是省略了AUTHORIZATION子句,則MyRole1爲當前數據庫用戶所擁有。

Ø 角色是若干操做權限的集合,可是剛建立的角色是「空的」,沒有包含任何權限。爲使角色造成權限的集合,須要利用GRANT等語句對空角色「填充」權限。

Ø 刪除自定義數據庫角色可用語句DROP ROLE來完成。該語句的語法以下:

DROP ROLE role_name

     其中,role_name爲要刪除的角色的名稱。

 

 

【例12.2】自定義數據庫角色刪除實例。

Ø 下列語句用於刪除自定義數據庫角色MyRole2:

DROP ROLE MyRole2;

Ø 沒法從數據庫中刪除擁有安全對象的角色。若要刪除擁有安全對象的數據庫角色,必須首先轉移這些安全對象的全部權,或從數據庫刪除它們。沒法從數據庫中刪除擁有成員的角色。若要刪除有成員的角色,必須首先刪除角色的成員。

Ø 不能使用DROP ROLE刪除固定數據庫角色。

 

 

12.2.3 應用程序角色

Ø 應用程序角色是用於給應用程序(而不是數據庫角色或用戶)分配權限的一種數據庫級角色。當應用程序鏈接到數據庫、激活應用程序角色,該應用程序將擁有應用程序角色所具備的全部權限,但這些權限只在鏈接期間有效。應用程序角色使用兩種身份驗證模式,但是使用sp_setapprole來激活,激活時須要密碼(由應用程序提供)。

 

 

Ø 應用程序角色具備如下特色:

•          應用程序角色不包含成員,這與數據庫角色不一樣。

•          當客戶端應用程序向系統存儲過程sp_setapprole提供應用程序角色名稱和密碼時,可激活應用程序角色。

•          密碼必須存儲在客戶端計算機上,而且在運行時提供;應用程序角色沒法從SQL Server內激活。

•          密碼不加密。從SQL Server 2005開始,參數密碼做爲單向散列存儲。

•          一旦激活,經過應用程序角色獲取的權限在鏈接期間保持有效。

•          應用程序角色繼承授予public角色的權限。

•          若是固定服務器角色sysadmin的成員激活某一應用程序角色,則安全上下文在鏈接期間切換爲應用程序角色的上下文。

 

第12章數據的安全性控制

•    12.1 SQL Server 2014安全體系結構

•    12.2 角色

•    12.3 服務器級的安全控制

•    12.4 數據庫級的安全控制

•    12.5 架構級的安全控制

 

12.3.1 身份驗證模式

Ø 身份驗證模式是指SQL Server確認用戶的方式。SQL Server用戶有兩種來源:一種是Windows受權的用戶(簡稱Windows用戶,此處的Windows是指Windows NT或Windows 2000及其以上的版本),即這種用戶的帳號和密碼是由Windows操做系統創建、維護和管理的,對SQL Server而言它們是來自Windows操做系統,只不過是由SQL Server確認爲SQL Server用戶而已;另外一種是SQL Server受權的用戶,這種用戶的帳號和密碼是由SQL Server服務器建立、維護和管理,與Windows操做系統無關。

Ø SQL Server爲這兩種不一樣類型的用戶提供了不一樣的身份驗證模式。

 

 

1. Windows身份驗證模式

Ø 在這種認證模式下,SQL Server容許Windows用戶鏈接到SQL Server服務器,即這種用戶只要可以登陸Windows,再登陸SQL Server時就不須要進行身份認證了。登陸界面如圖12.3所示。

 

 

 

 

 

 

 

 

 

 

2. SQL Server驗證模式

Ø 在這種驗證模式下,當用戶要登陸SQL Server時,SQL Server服務器要對登陸的用戶進行身份認證,即必須提供有效的登陸名和密碼,這些登陸名和密碼是保存在SQL Server數據庫中,與Windows無關。SQL Server驗證模式登陸界面如圖12.4所示。

 

 

 

 

 

 

 

 

 

 

Ø 注意,登陸服務器時,「服務器類型」下拉框中要選擇「數據庫引擎」一項,表示要登陸到數據庫服務器。

 

 

12.3.2 建立登陸

1. CREATE LOGIN的基本語法

建立登陸服務器賬號的SQL語句是CREATE LOGIN,其語法以下:

CREATE LOGIN loginName { WITH <option_list1> | FROM <sources> }

其中:

<option_list1> ::=

    PASSWORD = { 'password' | hashed_password HASHED } [ MUST_CHANGE ]

    [ , <option_list2> [ ,... ] ]

 

<option_list2> ::= 

    SID = sid

    | DEFAULT_DATABASE = database   

    | DEFAULT_LANGUAGE = language

    | CHECK_EXPIRATION = { ON | OFF}

    | CHECK_POLICY = { ON | OFF}

    | CREDENTIAL = credential_name

 

 

 

u 對涉及的參數說明以下:

Ø loginName

    指定建立的登陸名。有四種類型的登陸名:SQL Server登陸名、Windows登陸名、證書映射登陸名和非對稱密鑰映射登陸名。若是從Windows 域賬戶映射loginName,則loginName必須用方括號([ ])括起來。

Ø PASSWORD = 'password‘

    指定正在建立的登陸名的密碼,僅適用於SQL Server登陸名。密碼應保持必定的長度,最好是各類字符的組合,不能使用如生日之類的、別人容易猜想的密碼。

Ø PASSWORD = hashed_password

    指定要建立的登陸名的密碼的哈希值,僅適用於HASHED關鍵字。

Ø HASHED

    指定在PASSWORD參數後輸入的密碼已通過哈希運算,僅適用於SQL Server 登陸名。若是未選擇此選項,則在將做爲密碼輸入的字符串存儲到數據庫以前,對其進行哈希運算。

 

 

Ø MUST_CHANGE

    若是選擇此選項,則SQL Server將在首次使用新登陸名時提示用戶輸入新密碼,即強迫用戶更改密碼。僅適用於SQL Server登陸名。

Ø  CREDENTIAL = credential_name

    指定映射到新SQL Server登陸名的憑據的名稱。該憑據必須已存在於服務器中。當前此選項只將憑據連接到登陸名。在將來的SQL Server 版本中可能會擴展此選項的功能。

Ø  SID = sid

    指定新SQL Server登陸名的GUID。若是未選擇此選項,則SQL Server自動指派GUID。僅適用於SQL Server登陸名。

Ø  DEFAULT_DATABASE = database

    指定將指派給登陸名的默認數據庫。若是未包括此選項,則默認數據庫將設置爲master。

 

 

Ø  DEFAULT_LANGUAGE = language

     指定將指派給登陸名的默認語言。若是未包括此選項,則默認語言將設置爲服務器的當前默認語言。即便未來服務器的默認語言發生更改,登陸名的默認語言也仍保持不變。

Ø  CHECK_EXPIRATION = { ON | OFF }

   指定是否對此登陸賬戶強制實施密碼過時策略。默認值爲OFF,表示不強制。此選項僅適用於SQL Server登陸名。

Ø  CHECK_POLICY = { ON | OFF }

     指定應對此登陸名強制實施運行SQL Server的計算機的Windows密碼策略。默認值爲ON。僅適用於SQL Server 登陸名。

     只有CHECK_POLICY設置爲ON時,才能指定MUST_CHANGE選項,CHECK_EXPIRATION才能設置爲ON。

 

 

Ø  WINDOWS

     指定將登陸名映射到Windows登陸名。

Ø  CERTIFICATE certname

    指定將與此登陸名關聯的證書名稱。此證書必須已存在於master數據庫中。

Ø  ASYMMETRIC KEY asym_key_name

    指定將與此登陸名關聯的非對稱密鑰的名稱。此密鑰必須已存在於master數據庫中。

 

 

2. 建立SQL Server登陸

Ø SQL Server sa是在建立數據庫實例時設置的登陸名,它具備最高的權限,能夠在服務器上執行任何操做。

Ø 除了修改密碼之外,用戶不能對sa進行刪除或任何其餘修改操做。經過利用sa登陸服務器,用戶能夠建立具備不一樣權限的各級登陸賬號。

Ø 在本小節中將介紹SQL Server 2014服務器登陸名及其密碼等的建立、修改和刪除方法。

 

 

    【例12.3】  以最簡潔方式建立SQL Server登陸名並設置密碼。

Ø 這是較簡單也是最經常使用登陸名建立方法,代碼以下:

CREATE LOGIN myLogin1 WITH PASSWORD = '123456';

GO

    其中,myLogin1爲登陸名,密碼爲123456。執行該語句後便可用myLogin1登陸服務器了。但該語句沒有顯式指定默認數據庫,SQL Server會自動將master設置爲默認數據庫,所以登陸myLogin1指定打開master數據庫。

Ø 若是在密碼設置項後面再加上選項MUST_CHANGE,則在第一次用myLogin1登陸服務器時會強制用戶更改密碼。

Ø 須要說明的是,在實際應用中密碼應由字母、數字等多種字符構成,過於簡單的密碼容易被破解。這裏設置得比較簡單是爲了方便說明問題,實際應用中必定不能這麼設置。

 

 

【例12.4】建立一個指定默認數據庫的SQL Server登陸名。

Ø 利用例12.3建立的登陸myLogin1登陸服務器後發現,咱們僅能訪問master數據庫。緣由在於,建立該登陸時並無顯式指定默認數據庫,所以master自動被設置爲默認數據庫。

Ø 在本例中,建立名爲myLogin2的登陸,其密碼亦爲123456,但其默認數據庫指定爲MyDatabase。

        CREATE LOGIN myLogin2

WITH PASSWORD = '123456',

DEFAULT_DATABASE = MyDatabase;   -- 指定默認數據庫

GO

 

 

Ø 因爲指定了master數據庫之外的數據庫——MyDatabase做爲默認數據庫,所以必須建立一個基於此登陸的數據庫用戶,不然myLogin2不能正常登陸服務器。如下爲數據庫MyDatabase添加數據庫用戶myLogin2(與登陸名同名)

USE MyDatabase;

EXEC sp_grantdbaccess 'myLogin2';  -- 建立同名的數據庫用戶名

GO

Ø 也能夠利用CREATE USER語句建立一個與myLogin2不一樣名的數據庫用戶名User_myLogin2,但必須指定將該用戶映射到myLogin2:

USE MyDatabase;

CREATE USER User_myLogin2 FOR LOGIN myLogin2;

Ø 執行上述代碼,建立登陸myLogin2,而後用該登陸名登陸服務器。

 

 

3. 建立Windows登陸

Ø 建立Windows登陸名就是將已有的Windows用戶名設置爲SQL Server服務器的登陸名。所以,待設置的Windows用戶名必須是已經存在的,而後利用CREATE LOGIN語句將之設置爲服務器的登陸名。

 

 

   【例12.5】建立Windows登陸名。

    首先用Windows系統的控制面板建立一個名爲sql2014的Windows用戶,而後利用下列代碼將之設置爲SQL Server服務器的登陸名:

CREATE LOGIN [MZQ\sql2014]

FROM WINDOWS

WITH DEFAULT_DATABASE = MyDatabase; -- 指定默認數據庫

GO

USE MyDatabase;

GO

EXEC sp_grantdbaccess 'MZQ\sql2014';  -- 建立同名的數據庫用戶名(必須)

GO

      其中,MZQ爲筆者機器的機器名(即計算機名),「[MZQ\sql2014]」中的方括號不能省略。

執行上述代碼,建立Windows登陸名sql2014,而後切換到Windows用戶sql2014,登陸數據庫時選擇Windows認證驗證方式並選擇用戶sql2014便可登陸數據庫。

 

 

12.3.3 查看登陸

1. 查看全部的登陸

Ø 服務器級主體的信息保存在系統目錄視圖sys.server_principals中,所以,經過查詢系統目錄視圖sys.server_principals能夠得到登陸名的相關信息。

     

    【例12.6】查看服務器登陸名的基本信息。

      SQL Server登陸名和Windows登陸名的type列值分別爲‘S’和‘U’,所以能夠利用下列SELECT語句來查詢服務器登陸名的基本信息:

 

SELECT name 登陸名,type_desc 類型說明,is_disabled '禁用/啓用',create_date 建立時間,

                 modify_date 最近修改時間, default_database_name 默認數據庫,default_language_name

                 默認語言

FROM sys.server_principals

WHERE type = 'S' OR type = 'U’;

 

    執行該SELECT便可看到當前服務器上全部登陸的基本信息。

 

 

2. 查看當前登陸

Ø  函數SYSTEM_USER可用於返回當前的登陸的名稱。若是當前用戶使用Windows身份驗證登陸到SQL Server,則SYSTEM_USER返回以下形式的Windows登陸標識名稱:

DOMAIN\user_login_name

Ø 若是當前用戶使用SQL Server身份驗證登陸到SQL Server,則SYSTEM_USER返回SQL Server登陸標識名稱,例如爲以myLogin1登陸的用戶返回myLogin1。

 【例12.7】  查看當前登陸名。

PRINT SYSTEM_USER;

    筆者使用sa登陸,故執行上述語句後輸出:sa。

 

 

12.3.4 登陸的權限管理

1. 對登陸授予權限

Ø 對登陸受權是指將對服務器級安全對象(包括端點、登陸用戶和數據庫)的操做權限賦給登陸用戶,使得該登陸用戶能夠對此服務器級安全對象執行相應的操做。每個剛建立的登陸,會自動成爲角色public的成員。但這種成員僅僅擁有公衆訪問權,而沒有任何的操做權。因此,對剛建立的登陸(如myLogin1),雖然能夠鏈接服務器和打開其默認的數據庫,但它幾乎不能作任何事情。爲此,須要對它們受權,這樣它們才能具備執行相關操做的權力。咱們能夠從兩種途徑對登陸用戶受權:一種是利用GRANT語句,另外一種是利用服務器角色。

 

 

(1)利用GRANT語句

利用GRANT語句能夠對登陸用戶授予對服務器級主體的操做權限,其語法以下:

GRANT permission [ ,...n ] }

    ON LOGIN :: SQL_Server_login

        TO <server_principal> [ ,...n ]

    [ WITH GRANT OPTION ]

    [ AS SQL_Server_login ]

其中:

<server_principal> ::=

        SQL_Server_login

    | SQL_Server_login_from_Windows_login

    | SQL_Server_login_from_certificate

    | SQL_Server_login_from_AsymKey

 

 

對涉及的參數說明以下:

ü permission

    指定可對SQL Server登陸用戶授予的權限。這些權限可用下列SELECT語句查看:

SELECT DISTINCT permission_name

FROM sys.fn_builtin_permissions('SERVER');

ü LOGIN :: SQL_Server_login

    指定要對其授予權限的登陸名,::爲做用域限定符,必須使用。

ü TO <server_principal>

   指定要向其授予權限的服務器級主體的名稱。

ü SQL_Server_login

   指定SQL Server登陸用戶的名稱。

ü SQL_Server_login_from_Windows_login

   指定經過Windows登陸賬戶建立的SQL Server登陸用戶的名稱。

 

ü  SQL_Server_login_from_certificate

    指定映射到證書的SQL Server登陸用戶的名稱。

ü  SQL_Server_login_from_AsymKey

    指定映射到非對稱密鑰的SQL Server登陸用戶的名稱。

ü  WITH GRANT OPTION

    指示該主體還能夠向其餘主體授予所指定的權限。

ü  AS SQL_Server_login

    指定執行此查詢的主體要從哪一個SQL Server登陸用戶派生其授予該權限的權限。

 

  注意:只有在當前數據庫爲master時,纔可授予其服務器做用域內的權限。

 

 

【例12.8】對登陸用戶受權。

Ø 在下列代碼中,將對登陸用戶myLogin1的IMPERSONATE操做權限賦給Windows用戶MZQ\sql2014:

USE master;

GRANT IMPERSONATE ON LOGIN::myLogin1 to [MZQ\sql2014];

Ø 此後,MZQ\sql2014用戶能夠對myLogin1用戶執行IMPERSONATE操做。

Ø 若是還但願MZQ\sql2014用戶具備建立數據庫的權限,則可經過下列語句將CREATE ANY DATABASE權限賦給它:

USE master;

GRANT CREATE ANY DATABASE to [MZQ\sql2014];

 

 

(2)利用服務器角色

Ø 角色的成員擁有該角色所包含的全部權限。所以,經過將一個登陸用戶添加爲一個服務器角色的方法,能夠到達對登陸用戶受權的目的。

Ø 向服務器角色添加成員可利用系統存儲過程sp_addsrvrolemember來完成。該存儲過程的語法以下:

sp_addsrvrolemember [ @loginame= ] 'login'

    , [ @rolename = ] 'role‘

 

      其中,login爲要添加到固定服務器角色中的登陸名,role爲要添加登陸的固定服務器角色的名稱。添加成功時sp_addsrvrolemember返回0,不然返回1。

 

 

【例12.9】建立登陸,並對它授予超級權限。

Ø 角色sysadmin擁有全部的操做權限,即爲所謂的超級權限。如下先建立名爲myLogin3的登陸,而後將之添加成爲服務器角色sysadmin的成員,從而擁有超級權限。

CREATE LOGIN myLogin3

WITH PASSWORD = '123456',

DEFAULT_DATABASE = MyDatabase;   -- 指定默認數據庫

GO

USE MyDatabase;

GO

EXEC sp_grantdbaccess 'myLogin3';  

GO

EXEC sp_addsrvrolemember 'myLogin3', 'sysadmin';  -- 將myLogin3添加爲sysadmin的成員

GO

          執行上述代碼後,建立的myLogin3將與sa具備一樣的操做權限。

 

 

2. 對登陸收回權限

(1)利用REVOKE語句

Ø 對於利用GRANT語句向登陸授予的權限,能夠利用REVOKE語句對其收回。針對服務器權限的收回,REVOKE語句的語法以下:

REVOKE [ GRANT OPTION FOR ] permission [ ,...n ] }

    ON LOGIN :: SQL_Server_login

    { FROM | TO } <server_principal> [ ,...n ]

    [ CASCADE ]

    [ AS SQL_Server_login ]

   其中:

<server_principal> ::=

        SQL_Server_login

    | SQL_Server_login_from_Windows_login

    | SQL_Server_login_from_certificate

    | SQL_Server_login_from_AsymKey  

 

 

 

【例12.10】對登陸收回指定的收權。

Ø 下列代碼用於對登陸用戶MZQ\sql2014收回對IMPERSONATE權限(對登陸myLogin1)以及CREATE ANY DATABASE權限:

USE master;

REVOKE IMPERSONATE ON LOGIN::myLogin1 FROM [MZQ\sql2014];

REVOKE CREATE ANY DATABASE FROM [MZQ\sql2014];

 

 

 

(2)利用服務器角色

Ø 對於已經是某個服務器角色成員的登陸,若是取消它的成員身份,那麼它原來擁有的該角色權限也將自動被取消,從而達到收回權限的目的。

Ø 從服務器角色中刪除成員的操做可用系統存儲過程sp_dropsrvrolemember來完成。該存儲過程的語法以下:

sp_dropsrvrolemember [ @loginame = ] 'login' , [ @rolename = ] 'role‘;

      其中,login爲要從服務器角色中刪除的登陸的名稱,role爲從其中刪除成員的服務器角色的名稱。添加成功時sp_dropsrvrolemember返回0,不然返回1。

 

【例12.11】刪除服務器角色的成員。

      將登陸myLogin3從服務器角色sysadmin中刪除:

EXEC sp_dropsrvrolemember ‘myLogin3’, ‘sysadmin’     

執行上述代碼後,登陸myLogin3幾乎失去全部的操做權限(除非它還擁有其餘角色權限)。

 

 

3. 對登陸拒絕權限

Ø 對登陸拒絕權限是指拒絕已對登陸用戶授予的權限,這可利用DENY語句來實現。被拒絕的權限多是由GRANT語句授予的,也多是經過服務器角色成員資格繼承的權限。與DENY語句不一樣的是,REVOKE語句不能收回經過服務器角色成員資格繼承的權限,但DENY語句能夠「收回」這些權限。

 

 

用於拒絕服務器權限的DENY語句的語法以下:

DENY permission [ ,...n ] }

    ON LOGIN :: SQL_Server_login

    TO <server_principal> [ ,...n ]

    [ CASCADE ]

    [ AS SQL_Server_login ]

   其中:

<server_principal> ::=

        SQL_Server_login

    | SQL_Server_login_from_Windows_login

    | SQL_Server_login_from_certificate

    | SQL_Server_login_from_AsymKey  

該語法中涉及的參數的意義與上小節中介紹的REVOKE語句同樣,故再也不做說明。

 

 

【例12.12】拒絕對登陸名的IMPERSONATE 權限。

Ø 拒絕登陸MZQ\sql2014對myLogin1的IMPERSONATE權限,代碼以下:

USE master;

DENY IMPERSONATE ON LOGIN::myLogin1 TO [MZQ\sql2014];

 

【例12.13】拒絕登陸用戶擁有服務器角色中指定的權限。

Ø 服務器角色serveradmin包含了SHUTDOWN等服務器級權限,當登陸MZQ\sql2014被添加成爲該服務器角色成員時,它自動擁有該角色包含的全部權限。若是拒絕登陸MZQ\sql2014擁有SHUTDOWN權限,但讓它擁有serveradmin中的其餘權限時,可利用下列語句來實現:

USE master;

EXEC sp_addsrvrolemember [MZQ\sql2014], ‘serveradmin’;

                                                                              --將MZQ\sql2014添加爲serveradmin的成員

DENY SHUTDOWN TO [MZQ\sql2014];       -- 拒絕serveradmin中的SHUTDOWN權限

 

 

12.3.5 刪除登陸

Ø 登陸的刪除可利用SQL的DROP LOGIN語句來實現,該語句的語法以下:

DROP LOGIN login_name

    其中,login_name爲要刪除的登陸名。

 

【例12.14】刪除已有的登陸。

     對於已存在的登陸myLogin2,可用下列語句刪除:

DROP LOGIN myLogin2;

    

   注意:不能刪除SQL Server sa登陸,不能刪除正在使用的登陸,也不能刪除擁有任何安全對象、服務器級對象或SQL Server 代理做業的登陸。此外,不能同時刪除多個登陸。

 

第12章數據的安全性控制

•    12.1 SQL Server 2014安全體系結構

•    12.2 角色

•    12.3 服務器級的安全控制

•    12.4 數據庫級的安全控制

•    12.5 架構級的安全控制

 

12.4.1 數據庫用戶的管理

Ø 服務器登陸名用於鏈接SQL Server服務器,但它不能訪問數據庫,只有數據庫用戶才能訪問數據庫。所以,在建立服務器登陸名之後,還須要建立相應的數據庫用戶。一個數據庫能夠擁有多個數據庫用戶,一個數據庫用戶也能夠訪問多個數據庫(在有權限的前提下)。但有一點是共同的,即全部數據庫用戶老是與某一個登陸名相關聯(依賴於一個登陸名),且只能關聯(依賴)一個登陸名。所以,對一個登陸名,能夠建立多個與它相關聯的其餘數據庫用戶,從而能夠經過一個登陸名訪問多個數據庫。

 

1. 兩個特殊的數據庫用戶——dbo和guest

       在SQL Server 2014中,建立數據庫時會自動生成兩個特殊的數據庫用戶——dbo和guest。dbo在數據庫範圍內擁有最高的權限,能夠執行一切操做。固定服務器角色sysadmin的任何成員都映射到每一個數據庫內的用戶dbo上。

 

 

【例12.15】建立一個超級登陸用戶。

Ø 先建立登陸AdminUser,而後將之添加到固定服務器角色sysadmin中,AdminUser便可造成一個超級登陸用戶,它能夠管理一切事務。代碼以下:

CREATE LOGIN AdminUser WITH PASSWORD = '123456',

DEFAULT_DATABASE = MyDatabase;   -- 指定默認數據庫

GO

EXEC sp_addsrvrolemember 'AdminUser', 'sysadmin';  -- 將AdminUser添加爲sysadmin的成員

Ø 執行上述代碼後便可造成登陸AdminUser,它自動映射到全部數據庫內的用戶dbo上,所以就不須要爲之建立數據庫用戶了。

Ø guest用戶容許任何已經登陸到SQL Server服務器的用戶均可以訪問數據庫,但訪問的前提是須要對該用戶授予CONNECT權限。

 

 

【例12.16】建立一個guest登陸用戶。

Ø 下面建立一個guest登陸用戶,用戶名爲GusetUser,使之能夠訪問數據庫MyDatabase和DB_test,但沒有任何操做權限(包括SELECT等)。代碼以下:

CREATE LOGIN GusetUser WITH PASSWORD = '123',

DEFAULT_DATABASE = MyDatabase;    -- 指定默認數據庫

GO

USE MyDatabase;

GRANT CONNECT TO GUEST;

USE DB_test;

GRANT CONNECT TO GUEST;

Ø  執行上述代碼後,建立登陸GusetUser。若是要禁用GUEST用戶,可經過執行下列語句來收回SELECT權限,從而使GUEST失效:

REVOKE CONNECT TO GUEST;

注意:用戶dbo和guest都不能被刪除。另外,若是要查看當前在使用的登陸名和數據庫用戶名,則可利用函數SYSTEM_USER和USER_NAME()來完成:

PRINT '當前登陸名:'+SYSTEM_USER;

PRINT '當前數據庫用戶名:'+USER_NAME();

 

 

 

2. 建立數據庫用戶

Ø 除了兩個特殊的數據庫用戶——dbo和guest之外,咱們也可使用CREATE USER語句建立數據庫用戶。CREATE USER語句的語法以下:

CREATE USER user_name

    [ { { FOR | FROM }

      {

        LOGIN login_name

        | CERTIFICATE cert_name

        | ASYMMETRIC KEY asym_key_name

      }

      | WITHOUT LOGIN

    ]

    [ WITH DEFAULT_SCHEMA = schema_name ]

Ø 在CREATE USER語句中,若是省略FOR LOGIN子句,則必須數據庫用戶名user_name必須與其所依賴的登陸名同名(不然不能建立該數據庫用戶),表示將建立的數據庫用戶映射到同名的服務器登陸。

 

 

u 對涉及參數說明以下:

Ø user_name

指定在此數據庫用戶的名稱。

Ø LOGIN login_name

   指定所依賴的服務器登陸名。login_name必須是服務器中已建立的有效的登陸名。當此SQL Server登陸名進入數據庫時,它將獲取正在建立的數據庫用戶的名稱和ID。

Ø CERTIFICATE cert_name

指定要建立數據庫用戶的證書。

Ø ASYMMETRIC KEY asym_key_name

指定要建立數據庫用戶的非對稱密鑰。

Ø WITH DEFAULT_SCHEMA = schema_name

    指定服務器爲此數據庫用戶解析對象名時將搜索的第一個架構。若是不指定schema_name,則數據庫用戶將使用dbo做爲默認架構。注意,在建立映射到Windows組、證書或非對稱密鑰的用戶時,不能指定schema_name。

Ø WITHOUT LOGIN

指定不該將用戶映射到現有登陸名。

 

 

【例12.17】利用服務器登陸建立數據庫用戶。

Ø 首先建立名爲myLogin4的服務器登陸,其密碼爲'123456',而後基於myLogin4建立數據庫MyDatabase的用戶(登陸名與數據庫用戶名同名)。代碼以下:

CREATE LOGIN myLogin4 WITH PASSWORD = '123456';

GO

USE MyDatabase;         -- 必須指定數據庫

GO

CREATE USER myLogin4; -- 基於myLogin4建立同名的數據庫用戶

Ø 這是最簡單的數據庫用戶建立方法,由於在CREATE USER語句中只指定了數據庫用戶名myLogin4,並不顯式指定所依賴的登陸名(省略了FOR LOGIN子句)。但在這種最簡單的方式中,要求所使用的數據庫用戶名必須與其依賴的登陸名同名。

 

 

【例12.18】基於一個登陸建立多個數據庫用戶。

本實例展現如何利用一個登陸來建立多個數據庫的用戶。

(1)首先建立登陸myLogin5:

CREATE LOGIN myLogin5 WITH PASSWORD = '123456';

GO

(2)建立三個數據庫DB_test一、DB_test二、DB_test3:

CREATE DATABASE DB_test1;

GO

CREATE DATABASE DB_test2;

GO

CREATE DATABASE DB_test3;

GO

 

 

(3)基於登陸myLogin5建立數據庫DB_test1的用戶DB_user1:

USE DB_test1;   -- 指定數據庫(必須)

GO

CREATE USER DB_user1 FOR LOGIN myLogin5;

GO

         一樣,建立數據庫DB_test二、DB_test3的用戶,分別爲DB_user2和DB_user3:

USE DB_test2;   -- 指定數據庫(必須)

GO

CREATE USER DB_user2 FOR LOGIN myLogin5;

GO

USE DB_test3;   -- 指定數據庫(必須)

GO

CREATE USER DB_user3 FOR LOGIN myLogin5;

GO

 

 

u 讀者可能注意到,雖然對數據庫DB_test一、DB_test2和DB_test3分別建立了用戶DB_user一、DB_user2和DB_user3,但在登陸服務器時好像只使用了登陸名和登陸密碼就能夠進入這三個數據庫,而並無用到用戶名DB_user一、DB_user2和DB_user3。那麼,數據庫用戶DB_user一、DB_user2和DB_user3在登陸數據庫時起什麼做用呢?

 

  答:實際上,在利用登陸名成功鏈接服務器後,試圖進入某個數據庫時,SQL Server登陸名將獲取該數據庫用戶的名稱和ID,而後做相應的驗證才能進入數據庫。可見,登陸名隱式使用數據庫用戶。若是沒有這些數據庫用戶,登陸名是不能訪問數據庫的。

 

3. 查看數據庫用戶

系統存儲過程sp_helpuser可用於查看當前數據庫中數據庫級主體的信息,其語法以下:

sp_helpuser [ [ @name_in_db = ] 'security_account‘ ]

 

     其中,security_account爲當前數據庫中數據庫用戶或數據庫角色的名稱。security_account必須存在於當前數據庫中。若是未指定security_account,則sp_helpuser返回有關全部數據庫用戶的信息,其結構如表12.4所示。

 

 

 

【例12.19】利用sp_helpuser查看當前數據庫的全部數據庫用戶。

下列代碼用於查詢數據庫MyDatabase中的全部數據庫用戶及其相關信息:

USE MyDatabase;    -- 指定數據庫

GO

sp_helpuser; 

 

    在筆者機器上執行上述代碼,結果如圖12.5所示。

 

 

 

 

 

 

 

從圖12.5容易看出,哪一用戶擁有哪一個角色以及依賴於哪一個登陸等,一目瞭然。

 

 

 

Ø  在編寫SQL代碼的時候,可能須要得到當前數據庫用戶或指定數據庫用戶的名稱,這時能夠利用函數USER_NAME來完成。該函數的語法以下:

USER_NAME ( [ id ] )

 

    其中,id表示指定的數據庫用戶的id。id是可選的,若是沒有指定id,則返回當前數據庫用戶的名稱。

 

  【例12.20】  查看當前數據庫用戶的名稱。

    筆者在本次登陸時使用了sa登陸。因爲該登陸自動映射到用戶dbo,因此下列語句在筆者機器上將返回dbo:

print USER_NAME();

 

 

4. 修改數據庫用戶

Ø 數據庫用戶的修改由ALTER USER語句來實現,其語法以下:

ALTER USER userName WITH <set_item> [ ,...n ]

    其中:

<set_item> ::=

     NAME = newUserName

     | DEFAULT_SCHEMA = schemaName

     | LOGIN = loginName

   其中,userName爲待修改的數據庫用戶名,newUserName爲修改後新的數據用戶名,loginName表示修改後的用戶要映射到的登陸名,schemaName爲新的架構名。

 

Ø 可見,利用ALTER USER語句能夠修改數據庫用戶的三個屬性值:數據庫用戶的名稱、架構和所依賴的登陸名。

 

 

【例12.21】修改數據庫用戶的架構和所依賴的登陸名。

    在本例中,先建立兩個登陸:myLogin6和myLogin7,而後爲數據庫MyDatabase建立用戶user1,並映射到myLogin6,最後將user1的架構和依賴的登陸分別改成Purchasing和myLogin7。代碼以下:

CREATE LOGIN myLogin6 WITH PASSWORD = 'akh8#Udfgsr7mAcxo3Bfe';

CREATE LOGIN myLogin7 WITH PASSWORD = 'akh8#Udfgsr7mAcxo3Bfe';

GO

USE MyDatabase;

GO

CREATE USER user1 FOR LOGIN myLogin6;

GO

ALTER USER user1 WITH DEFAULT_SCHEMA = Purchasing, LOGIN = myLogin7; --修改用戶

 

 

5. 刪除數據庫用戶

Ø 刪除數據庫用戶由DROP USER語句來完成,其語法以下:

DROP USER user_name

 

  其中,user_name爲刪除的數據庫用戶的名稱。

 

【例12.22】刪除數據庫用戶。

   將數據庫MyDatabase的用戶user1刪除,代碼以下:

 DROP USER user1;

 

 

12.4.2 安全對象的權限管理

Ø 數據庫級主體能夠對數據庫級安全對象執行相關操做,但這種操做是有前提的,即數據庫級主體必須擁有與數據庫級安全對象相關的權限。也就是說,只有擁有相關的權限後,數據庫級主體才能對數據庫級安全對象執行對應的操做。

Ø 數據庫級安全對象包括用戶、角色、應用程序角色、程序集、消息類型、路由、服務、遠程服務綁定、全文目錄、證書、非對稱密鑰、對稱密鑰、約定、架構等。數據庫級主體包括數據庫用戶、數據角色和應用程序角色。

 

 

u 給數據庫級主體受權——GRANT

•         給數據庫級主體受權是指將數據庫級安全對象的有關操做權限授予數據庫級主體,使該主體能夠對對應的安全對象執行相應的操做。固然,也能夠將其餘安全對象的操做權限賦給數據庫級主體。

•         因爲數據庫級安全對象包含的對象不少,限於篇幅,咱們不能一一介紹。下面主要經過舉例說明如何將對一個數據庫級安全對象的操做權限賦給另外一個數據庫級安全對象,以及將對數據庫的操做權限(如CREATE TABLE、CREATE VIEW等)賦給另外一個數據庫級安全對象。

•         也能夠經過利用角色來對主體受權,即便主體成爲角色的成員。

 

 

(1)將對數據庫級主體的操做權限賦給(另外一個)數據庫級主體

利用GRANT語句能夠將對一個數據庫級主體的操做權限賦給另外一個數據庫級主體,語法以下:

 

GRANT permission [ ,...n ] 

    ON

    {  [ USER :: database_user ]

              | [ ROLE :: database_role ]

       | [ APPLICATION ROLE :: application_role ]

    }

    TO <database_principal> [ ,...n ]

    [ WITH GRANT OPTION ]

        [ AS <database_principal> ]

 

 

對涉及的參數說明以下:

Ø permission

   該參數表示可對數據庫主體授予的權限。

Ø USER :: database_user

   指定要對其授予權限的用戶的類和名稱。::爲做用域限定符,不能省略(下同)。

Ø ROLE :: database_role

   指定要對其授予權限的角色的類和名稱。

Ø APPLICATION ROLE :: application_role

   指定要對其授予權限的應用程序角色的類和名稱。

Ø WITH GRANT OPTION

   指示該主體還能夠向其餘主體授予所指定的權限。

Ø AS <database_principal>

   指定執行此查詢的主體要從哪一個主體派生其授予該權限的權限。

Ø Database_user

   指定數據庫用戶。

 

 

Ø  Database_role

    指定數據庫角色。

Ø  Application_role

   指定應用程序角色。

Ø  Database_user_mapped_to_Windows_User

   指定映射到Windows用戶的數據庫用戶。

Ø  Database_user_mapped_to_Windows_Group

   指定映射到Windows組的數據庫用戶。

Ø  Database_user_mapped_to_certificate

   指定映射到證書的數據庫用戶。

Ø  Database_user_mapped_to_asymmetric_key

  指定映射到非對稱密鑰的數據庫用戶。

Ø  Database_user_with_no_login

  指定無相應服務器級主體的數據庫用戶。

 

 

【例12.23】將對一個用戶的CONTROL權限賦給另外一個用戶。

Ø 做爲例子,下面先建立登陸myLogin8_1和myLogin8_2,而後基於這兩個登陸,分別建立數據庫MyDatabase的用戶User1和User2,最後將對用戶User2的CONTROL操做權限賦給用戶User1。代碼以下:

CREATE LOGIN myLogin8_1 WITH PASSWORD = '123456'; --建立登陸

GO

CREATE LOGIN myLogin8_2 WITH PASSWORD = '123456';

GO

USE MyDatabase;                                                  -- 指定數據庫(必須)

CREATE USER User1 FOR LOGIN myLogin8_1;   --建立數據庫用戶

GO

CREATE USER User2 FOR LOGIN myLogin8_2;

USE MyDatabase;

GRANT CONTROL ON USER::User2 TO User1;    -- 受權

 

 

u 對數據庫用戶的操做權限主要包括:CONTROL、IMPERSONATE、ALTER、VIEW DEFINITION;

u 對數據庫角色的操做權限主要包括:CONTROL、TAKE OWNERSHIP、ALTER、VIEW DEFINITION;

u 對應用程序角色的操做權限主要包括:CONTROL、ALTER、VIEW DEFINITION。

 

     讀者能夠模仿例12.23,將對一個數據庫級主體的操做權限賦給另外一個數據庫級主體。

 

 

 

1. 將對數據庫的操做權限賦給(一個)數據庫級主體

下列的GRANT語句的語法用於將對當前數據庫的操做權限賦給一個數據庫級主體:

GRANT <permission> [ ,...n ]  

    TO <database_principal> [ ,...n ] [ WITH GRANT OPTION ]

    [ AS <database_principal> ]

其中:

<permission>::= 

permission | ALL [ PRIVILEGES ]

 

<database_principal> ::=

        Database_user

    | Database_role

    | Application_role

    | Database_user_mapped_to_Windows_User

    | Database_user_mapped_to_Windows_Group

    | Database_user_mapped_to_certificate

    | Database_user_mapped_to_asymmetric_key

    | Database_user_with_no_login

 

 

Ø  能夠看出,此處的參數與前面介紹的GRANT語句語法中的參數絕大部分參數相同,不一樣的是如下三個參數:

p permission

    指定可授予的對數據庫的操做權限。這些權限可用下列SELECT語句來查看:

SELECT permission_name

FROM sys.fn_builtin_permissions('DATABASE');

p ALL

     該項表示同時授予下列權限:BACKUP DATABASE、BACKUP LOG、CREATE DATABASE、CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE TABLE和CREATE VIEW。但注意,它並不表示授予全部可能的權限。

p PRIVILEGES

    包含此參數是爲了符合ISO標準。

 

 

 【例12.24】將對數據庫的CREATE TABLE權限等賦給數據庫用戶。

Ø 下面代碼用於將對數據庫MyDatabase的CREATE TABLE、CREATE VIEW和CREATE PROCEDURE操做權限(分別表示對數據庫MyDatabase的建立表、建立視圖和建立存儲過程的權限)賦給數據庫用戶User1,代碼以下:

USE MyDatabase;

GRANT CREATE TABLE,CREATE VIEW,CREATE PROCEDURE TO User1;

Ø 執行上述代碼後,在利用User1登陸數據庫MyDatabase;時,就能夠在其中建立表、視圖和存儲過程。

 

 

【例12.25】讓一個數據庫用戶具備受權的全向。

ü 經受權後,有的用戶可能擁有很大的權限,但該用戶自己也許不能將其擁有的大量權限賦給別的用戶或角色。若是須要讓用戶可以將其擁有的權限賦給別的用戶或角色,則必須在對用戶受權時使用WITH GRANT OPTION選項。

ü 下面代碼用於將對角色MyRole1的VIEW DEFINITION操做權限賦給用戶user1,同時容許用戶user1將此權限賦給其餘的數據庫級主體(即用戶user1具備將對角色MyRole1的VIEW DEFINITION操做權限賦給其餘數據庫級主體的能力):

USE MyDatabase; 

GRANT VIEW DEFINITION ON ROLE:: MyRole1 TO user1 WITH GRANT OPTION;

 

 

2. 查看數據庫級安全對象上的權限——sp_helprotect

系統存儲過程sp_helprotect可用於查看數據庫級安全對象上的全部權限。sp_helprotect的語法以下:

sp_helprotect [ [ @name = ] 'object_statement' ]

     [ , [ @username = ] 'security_account' ]

     [ , [ @grantorname = ] 'grantor' ]

     [ , [ @permissionarea = ] 'type' ]

 

 

 

對涉及的參數說明以下:

Ø [ @name = ] 'object_statement‘

       指定當前數據庫或語句中具備報告權限的對象的名稱。默認值爲NULL,表示將返回全部的對象權限和語句權限。若是值爲一個對象(表、視圖、存儲過程或擴展存儲過程),則該對象必須是當前數據庫中的有效對象。

       若是object_statement是一個語句,則該語句能夠是下列語句之一:

•        CREATE DATABASE

•        CREATE DEFAULT

•        CREATE FUNCTION

•        CREATE PROCEDURE

•        CREATE RULE

•        CREATE TABLE

•        CREATE VIEW

•        BACKUP DATABASE

•        BACKUP LOG

 

 

Ø  [ @username = ] 'security_account’

     security_account表示爲其返回權限的主體的名稱。默認值爲NULL,表示將返回當前數據庫中的全部主體的權限。security_account必須存在於當前數據庫中。

Ø  [ @grantorname = ] 'grantor‘

    給其餘主體賦予權限的主體的名稱。默認值爲NULL,表示將返回數據庫中任意主體授予的權限的所有信息。

Ø  [ @permissionarea = ] 'type‘

    指示是顯示對象權限(字符串o)、語句權限(字符串s)仍是同時顯示二者(os) 的字符串。默認值爲os。type 能夠是o和s的任意組合,o和s之間能夠有也能夠沒有逗號和空格。

 

 

【例12.26】查看指定用戶所擁有的權限。

Ø 根據上面系統存儲過程sp_helprotect的語法,查看數據庫用戶User1所擁有的權限能夠利用下列語句來實現:

EXEC sp_helprotect @username = 'User1’;

 

Ø 或

EXEC sp_helprotect NULL,'User1‘;

 

      若是sp_helprotect不帶參數,則將返回全部對象的權限信息。

 

 

3. 對數據庫級主體收回權限——REVOKE

      在給某個數據庫級主體授予某些操做權限後,如何認爲沒有必要或不該該給它授予這些權限時,能夠利用REVOKE語句收回已授予的權限。

(1)收回已授予的對數據庫級主體的操做權限

     將對數據庫級主體的操做權限賦給另外一個數據庫級主體後,若是想收回已賦予的權限,則可用REVOKE語句的下列語法:

 

REVOKE [ GRANT OPTION FOR ] permission [ ,...n ] 

    ON

    {  [ USER :: database_user ]

       | [ ROLE :: database_role ]

       | [ APPLICATION ROLE :: application_role ]

    }

    { FROM | TO } <database_principal> [ ,...n ]

        [ CASCADE ]

    [ AS <database_principal> ]

 

 

 

u 上述語法中涉及的參數與前面介紹的GRANT語句語法中涉及的參數的意義基本相同。須要特別說明的是下列兩個參數:

Ø GRANT OPTION

     指示要撤消向其餘主體授予指定權限的權限,不會撤消該權限自己。但若是主體具備不帶GRANT選項的指定權限,則將撤消該權限自己。

Ø CASCADE

    指示要撤消的權限也會今後主體授予或拒絕該權限的其餘主體中撤消。

 

 

 

【例12.27】收回一個用戶擁有的對另外一個用戶的CONTROL操做權限。

     在例12.23中,將對用戶User2的CONTROL權限賦給用戶User1,現用REVOKE語句對用戶User1收回該權限,代碼以下:

USE MyDatabase;

REVOKE CONTROL ON USER:: User2 FROM User1;

 

 

【例12.28】收回一個用戶擁有的對其餘主體受權的權限。

     例12.25中,對用戶User1授予了對角色MyRole1的VIEW DEFINITION操做權限,並容許用戶User1將該權限賦給其餘主體。若是要收回用戶User1擁有的將對角色MyRole1的VIEW DEFINITION操做權限賦給其餘主體的權限(但不收回User1擁有的將對角色MyRole1的VIEW DEFINITION操做權限),則可用下列語句來實現:

USE MyDatabase;

REVOKE GRANT OPTION FOR VIEW DEFINITION ON ROLE:: MyRole1 FROM User1;

 

注意:執行上述語句後,User1仍然能夠執行對角色MyRole1的VIEW DEFINITION操做,只是不能將該操做權限賦給其餘主體而已。若是須要同時收回User1擁有的對角色MyRole1的VIEW DEFINITION操做權限,則可用下列語句實現:

USE MyDatabase;

REVOKE VIEW DEFINITION ON ROLE:: MyRole1 FROM User1 CASCADE;

 

 

(2)收回已授予的對數據庫的操做權限

將對當前數據庫的操做權限賦給一個數據庫級主體後,若是須要收回該操做權限,則可用REVOKE語句的下列語法:

 

REVOKE [ GRANT OPTION FOR ] <permission> [ ,...n ] 

    { TO | FROM } <database_principal> [ ,...n ]

        [ CASCADE ]

    [ AS <database_principal> ]

 

 

u 該語法涉及的參數與前面介紹的REVOKE語句語法涉及的參數的意義基本相同。須要注意的是如下兩個參數:

Ø ALL

    指定該選項時,表示同時收回下列權限:BACKUP DATABASE、BACKUP LOG、CREATE DATABASE、CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE TABLE 和CREATE VIEW。但不是全部的數據庫權限。

Ø PRIVILEGES

   包含此參數是爲了符合ISO 標準。請不要更改ALL 的行爲。

 

 

 【例12.29】收回數據庫用戶擁有的對數據庫的有關操做權限。

Ø 例12.24中,對用戶User1授予了對數據庫MyDatabase的CREATE TABLE、CREATE VIEW和CREATE PROCEDURE操做權限。若是須要將後面的兩個操做權限(CREATE VIEW和CREATE PROCEDURE),則可用下列語句實現:

USE MyDatabase;

REVOKE CREATE VIEW,CREATE PROCEDURE FROM User1;

 

Ø 執行上述語句後,用下列語句來查看用戶User1所擁有的數據庫權限,如圖12.6所示。這代表,CREATE VIEW和CREATE PROCEDURE權限確實已經被收回。

USE MyDatabase;

EXEC sp_helprotect @username = 'User1';

 

 

 

4. 對數據庫級主體拒絕權限——DENY

Ø 主體主要是經過兩種途徑得到對安全對象的操做權限,一種是利用GRANT語句對其受權,另外一個是經過組或角色成員資格繼承權限。利用REVOKE語句能夠收回由GRANT語句授予的權限,但不能收回經過組或角色成員資格繼承權限。所以,要完全地不容許主體擁有某一種操做權限,則最好使用DENY語句來實現。

Ø DENY語句語句的簡化語法以下:

DENY { ALL [ PRIVILEGES ] }

      | permission [ ( column [ ,...n ] ) ] [ ,...n ]

      [ ON [ class :: ] securable ] TO principal [ ,...n ]

      [ CASCADE] [ AS principal ]

 

 

【例12.30】拒絕對一個用戶授予對另外一個用戶的CONTROL權限。

Ø 下列代碼用於拒絕用戶User1 對MyDatabase用戶User2的CONTROL 權限:

USE MyDatabase;

DENY CONTROL ON USER::User2 TO User1;

此後,用戶User1不能執行對用戶User2的CONTROL操做。

 

【例12.31】拒絕一個用戶擁有對數據庫的CREATE TABLE權限。

Ø 下列代碼用於拒絕用戶User1擁有對數據庫MyDatabase的CREATE TABLE權限:

USE MyDatabase;

DENY CREATE TABLE TO User1;

Ø 此後,用戶User1不能執行對數據庫MyDatabase的CREATE TABLE操做,即User1不能在數據庫MyDatabase中建立數據表。除非執行下列語句,以將CREATE TABLE權限賦給用戶User1(解除拒絕):

USE MyDatabase;

GRANT CREATE TABLE TO User1;    -- 受權

 

第12章數據的安全性控制

•    12.1 SQL Server 2014安全體系結構

•    12.2 角色

•    12.3 服務器級的安全控制

•    12.4 數據庫級的安全控制

•    12.5 架構級的安全控制

 

12.5.1 架構及其管理

1. 架構的概念

Ø 架構(SCHEMA)是造成單個命名空間的數據庫對象的集合,它包括數據類型、XML架構集合和對象類,其中對象類又包括聚合、約束、函數、過程、隊列、統計信息、同義詞、表、視圖等。在同一個架構中不能存在重名的數據庫對象。

Ø  在一個架構中不容許存在同名的兩個表,只有在位於不一樣架構中的兩個表才能重名。從管理的角度看,架構是數據對象管理的邏輯單位。

Ø 在SQL Server 2000中沒有架構的概念,架構是自SQL Server 2005開始在SQL Server中出現的。實際上,在SQL Server 2000中架構和數據庫用戶是同一個概念,二者是合一的。自SQL Server 2005開始,架構與數據庫用戶分離了。具體講,在SQL Server 2000 中,數據庫用戶和架構是隱式鏈接在一塊兒的。每一個數據庫用戶都是與該用戶同名的架構的全部者。於是,SQL Server 2000 中的架構也就是數據庫中的用戶。

 

 

Ø  架構和數據庫用戶分離是SQL Server 2005對SQL Server 2000的一個重要改進。這種改進的好處體如今:

•         多個用戶能夠經過角色成員身份或Windows 組成員身份擁有一個架構。

•         有效簡化了刪除數據庫用戶的操做。

•         刪除數據庫用戶時,不須要對該用戶架構所包含的對象進行重命名。所以,在刪除建立架構所含對象的用戶後,再也不須要修改和測試顯式引用這些對象的應用程序。從而能夠有效較少系統開發的總工做量。

•         經過默認架構的共享,能夠實現統一名稱解析;並且經過架構的共享,開發人員能夠將共享對象存儲在爲特定應用程序專門建立的架構中,而不是DBO 架構中。

•         能夠用比SQL Server 2000中更大的粒度管理架構和架構包含的對象的權限。

Ø  在SQL Server 2014中,架構分爲兩種類型:一種是系統內置的架構,稱爲系統架構;另外一種是由用戶定義的架構,稱爲用戶自定義架構。

Ø  在建立數據庫用戶時,必須指定一個默認架構,即每一個用戶都有一個默認架構。若是不指定,則使用系統架構dbo做爲用戶的默認架構。服務器在解析對象的名稱時,第一個要搜索的架構就是用戶的默認架構。

 

 

2. 建立架構——CREATE SCHEMA

    建立架構的語法以下: 

CREATE SCHEMA schema_name_clause [ <schema_element> [ ...n ] ]

其中:

<schema_name_clause> ::=

    {

        schema_name

    | AUTHORIZATION owner_name

    | schema_name AUTHORIZATION owner_name

    }

 

<schema_element> ::=

    {

        table_definition | view_definition | grant_statement

        revoke_statement | deny_statement

    }

 

 

對涉及參數說明以下:

Ø schema_name

     指定待建立的架構的名稱,在數據庫內是惟一的。

Ø AUTHORIZATION owner_name

      指定將擁有架構的數據庫級主體(數據庫用戶或角色)的名稱。該主體能夠擁有包含當前架構在內的多個架構,而且能夠不使用當前架構做爲其默認架構。

Ø table_definition

      指定在架構內建立表的CREATE TABLE語句。執行此語句的主體必須對當前數據庫具備CREATE TABLE 權限。

Ø view_definition

       指定在架構內建立視圖的CREATE VIEW語句。執行此語句的主體必須對當前數據庫具備CREATE VIEW權限。

 

 

Ø grant_statement

     指定可對除新架構外的任何安全對象授予權限的GRANT語句。

Ø revoke_statement

     指定可對除新架構外的任何安全對象收回權限的REVOKE語句。

Ø deny_statement

    指定可對除新架構外的任何安全對象拒絕授予權限的DENY語句。

 

 

 

【例12.32】建立架構實例。

       如下代碼將建立名爲mySchema1的架構,其擁有者爲數據庫用戶User1,同時建立數據表T1(其所屬架構自動設置爲mySchema1)。此外,該架構建立語句還向User2授予SELECT權限,對用戶User2拒絕授予INSERT權限。

USE MyDatabase;

GO

CREATE SCHEMA mySchema1 AUTHORIZATION User1

    CREATE TABLE T1(c1 int, c2 int, c3 int)

    GRANT SELECT TO User2

    DENY INSERT TO User2;

 

 

3. 修改架構——ALTER SCHEMA

Ø 架構的修改主要包括在架構之間傳輸安全對象以及修改架構的擁有者。前者用ALTER SCHEMA語句來實現,後者則用ALTER AUTHORIZATION語句來完成。如下分別舉例說明。

【例12.33】  在架構之間傳輸安全對象。

       有時候須要將一個架構中的安全對象傳輸到另外一個架構中去,例如,將架構mySchema1中的安全對象——數據表T1傳輸到架構mySchema2中去,則可利用下列的ALTER SCHEMA語句來實現:

ALTER SCHEMA mySchema2 TRANSFER mySchema1.T1;

【例12.34】  修改架構的擁有者。

     將架構mySchema1的擁有者由原來的User1改成User2(即將mySchema1的全部權傳遞給User2),代碼以下:

ALTER AUTHORIZATION ON SCHEMA::mySchema1 TO User2;

 

 

4. 查看架構

【例12.35】查看當前數據庫中的全部架構。

    系統目錄視圖sys.schemas保存了當前數據庫中的全部架構信息,這些信息包含架構的名稱(name)、架構id(schema_id)和其擁有者的id(principal_id)。所以,利用下列語句能夠返回當前數據庫中的全部架構:

USE MyDatabase;    -- 指定當前數據庫

SELECT name 架構名

FROM sys.schemas;

 

 

【例12.36】查看架構的擁有者。

     架構的擁有者爲數據庫主體,這些主體信息包含在sys.database_principals中。所以,經過對sys.schemas和sys.database_principals的鏈接查詢便可得到架構的擁有者。代碼以下:

USE MyDatabase; 

SELECT a.name 架構, b.name 擁有者

FROM sys.schemas a

JOIN sys.database_principals b

ON a.principal_id = b.principal_id;

 

【例12.37】查看指定架構包含的對象。

    爲了觀看效果,下面代碼先在數據庫MyDatabase中建立架構mySchema3(其擁有者爲User1),而後在該架構內建立三個對象——數據表:T3_一、T3_2和T3_3,最後查詢架構mySchema3包含的對象。代碼以下:

USE MyDatabase;

GO

CREATE SCHEMA mySchema3 AUTHORIZATION User1;     -- 建立架構

GO

CREATE TABLE mySchema3.T3_1(c1 int, c2 int);      -- 建立架構內的對象

CREATE TABLE mySchema3.T3_2(c1 int, c2 int);

CREATE TABLE mySchema3.T3_3(c1 int, c2 int);

 

SELECT b.name 架構名, a.name 包含的對象名, a.type 對象類型      -- 查詢架構包含的對象

FROM sys.objects a

JOIN sys.schemas b

ON a.schema_id = b.schema_id

WHERE b.name = 'mySchema3';

 

 

5. 刪除架構——DROP SCHEMA

Ø 從數據庫中刪除架構可用DROP SCHEMA語句來實現,其語法以下:

      DROP SCHEMA schema_name; 

       schema_name表示待刪除的架構的名稱。但須要注意的是,要刪除的架構不能包含任何對象,不然刪除操做將失敗。

 

 

【例12.38】刪除架構實例。

      刪除在例12.37中建立的架構mySchema3,但該架構包含三個對象:表T3_一、T3_2和T3_3(可用前面介紹的方法查看一個架構包含的全部對象),所以須要刪除者三張數據表:

USE MyDatabase;

DROP TABLE mySchema3.T3_1, mySchema3.T3_2, mySchema3.T3_3;

       或者將利用ALTER SCHEMA... TRANSFER語句將架構mySchema3下的對象傳遞到其餘架構(如mySchema2)下:

USE MyDatabase;

ALTER SCHEMA mySchema2 TRANSFER mySchema3.T3_1

ALTER SCHEMA mySchema2 TRANSFER mySchema3.T3_2

ALTER SCHEMA mySchema2 TRANSFER mySchema3.T3_3

而後才能刪除架構mySchema3:

DROP SCHEMA mySchema3;  -- 刪除架構

 

 

6. 架構權限的管理

Ø 對架構的操做權限能夠賦給一個或多個數據庫級主體,也能夠對已授予的權限進行收回或禁用等操做,這些操做也分別使用GRANT、DENY、REVOKE語句來實現。

Ø 針對對架構的操做權限,其賦權操做由GRANT語句的下列語法完成:

GRANT permission  [ ,...n ] ON SCHEMA :: schema_name

    TO database_principal [ ,...n ]

    [ WITH GRANT OPTION ]

    [ AS granting_principal ]

    其中,對涉及的參數說明以下:

     (1) permission

          指定可授予的、對架構的操做權限。這些權限能夠利用下列語句查詢:

SELECT permission_name 權限名

FROM sys.fn_builtin_permissions('SCHEMA’);

 

 

 (2) ON SCHEMA :: schema_name

      設置此項時,表示將對其操做的權限賦給database_principal的架構,schema_name則表示該架構的名稱,須要範圍限定符「::」。

(3) database_principal

     指定要向其授予權限的主體,爲如下類型之一:

ü 數據庫用戶

ü 數據庫角色

ü 應用程序角色

ü 映射到Windows登陸名的數據庫用戶

ü 映射到Windows 組的數據庫用戶

ü 映射到證書的數據庫用戶

ü 映射到非對稱密鑰的數據庫用戶

ü 未映射到服務器主體的數據庫用戶

 

 

(4) GRANT OPTION

     指示該主體還能夠向其餘主體授予所指定的權限。

(5) AS granting_principal

      指定一個主體,執行該查詢的主體從該主體得到授予該權限的權利。該主體是如下類型之一:

ü 數據庫用戶

ü 數據庫角色

ü 應用程序角色

ü 映射到Windows 登陸名的數據庫用戶

ü 映射到Windows 組的數據庫用戶

ü 映射到證書的數據庫用戶

ü 映射到非對稱密鑰的數據庫用戶

ü 未映射到服務器主體的數據庫用戶

 

 

【例12.39】將對架構的操做權限賦給指定的數據庫主體。

Ø 下列代碼將對架構mySchema1的INSERT、UPDATE和DELETE權限賦給數據庫用戶User1:

USE MyDatabase;

GRANT INSERT,UPDATE,DELETE ON SCHEMA :: mySchema1 TO User1; 

Ø REVOKE、DENY語句GRANT語句的使用方法相似。例如,收回或拒絕User1對架構mySchema1的INSERT權限,可分別利用下面的語句來實現:

 

REVOKE INSERT ON SCHEMA :: mySchema1 TO User1; 

DENY INSERT ON SCHEMA :: mySchema1 TO User1;

 

12.5.2 安全對象的權限管理

Ø 架構級安全對象包括數據類型、XML架構集合和對象類,其中對象類又包括聚合、約束、函數、過程、隊列、統計信息、同義詞、表、視圖等。本節將重點介紹如何管理對對象類的操做權限。

Ø 能夠這樣形象地理解:服務器級和數據庫級的安全控制分別是對數據的最外層和次外層保護,而架構級的安全控制則是對數據最內層的保護,是數據的「貼身侍衛」。架構是安全對象在邏輯上的集合,若是一個主體擁有了對架構的訪問權限,那麼它對該架構內的全部安全對象都具備相應的訪問權限。若是以爲一個主體僅從架構那裏繼承來的權限還「不夠用」,咱們能夠單獨給它「開小竈」——將對對象的操做權限逐一地給它賦權,從而使該主體擁有足夠的權限。

Ø 下面將介紹如何將對架構級安全對象的操做權限賦給一個數據庫級主體,以及對這些權限的收回和拒絕等。

 

 

Ø  給一個主體授予對架構級安全對象(表、視圖、表值函數、存儲過程、擴展存儲過程、標量函數、聚合函數、服務隊列或同義詞)的操做權限,也可使用GRANT語句,相應的語法以下:

GRANT <permission> [ ,...n ] ON

    [ OBJECT :: ][ schema_name ]. object_name [ ( column [ ,...n ] ) ]

    TO <database_principal> [ ,...n ]

    [ WITH GRANT OPTION ]

    [ AS <database_principal> ]

 

 

 

該語法涉及的參數說明以下:

Ø permission

    指定能夠授予的對架構包含的對象的權限。這些權限能夠利用下列SELECT語句查看:

SELECT permission_name

FROM sys.fn_builtin_permissions('OBJECT');

Ø ALL

     選擇該項表示授予適用於指定對象的全部ANSI-92權限。對於不一樣權限,ALL 的含義有所不一樣:

ü 標量函數權限:EXECUTE、REFERENCES

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

ü 存儲過程權限:EXECUTE

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

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

 

 

Ø  PRIVILEGES

     選擇此參數是爲了符合ANSI-92標準,不會更改ALL的行爲。

Ø  column

     指定表、視圖或表值函數中要授予對其權限的列的名稱。括號( )是必須的。只能授予對列的SELECT、REFERENCES及UPDATE權限。column能夠在權限子句中指定,也能夠在安全對象名以後指定。

Ø  ON [ OBJECT :: ] [ schema_name ].object_name

    指定要授予對其權限的對象。若是指定了schema_name,則OBJECT短語是可選的,不然是必選的。若是使用了OBJECT短語,則須要做用域限定符(::)。若是未指定schema_name,則使用默認架構。若是指定了schema_name,則須要架構做用域限定符\(.)。

Ø  TO <database_principal>

    指定要向其授予權限的主體。

 

 

Ø  WITH GRANT OPTION

    選擇該選項表示該主體還能夠向其餘主體授予所指定的權限。

Ø  AS <database_principal>

     指定執行此查詢的主體要從哪一個主體派生其授予該權限的權限。

Ø  Database_user

    指定數據庫用戶。

Ø  Database_role

    指定數據庫角色。

Ø  Application_role

   指定應用程序角色。

Ø  Database_user_mapped_to_Windows_User

   指定映射到Windows 用戶的數據庫用戶。

 

 

Ø  Database_user_mapped_to_Windows_Group

   指定映射到Windows 組的數據庫用戶。

Ø  Database_user_mapped_to_certificate

   指定映射到證書的數據庫用戶。

Ø  Database_user_mapped_to_asymmetric_key

   指定映射到非對稱密鑰的數據庫用戶。

Ø  Database_user_with_no_login

   指定無相應服務器級主體的數據庫用戶。

 

 

 【例12.40】授予對錶的SELECT權限

       本例中,將對架構dbo內表student的SELECT權限賦給數據庫用戶User1,代碼以下:

        GRANT SELECT ON OBJECT::dbo.student TO User1;

 【例12.41】授予對存儲過程的EXECUTE權限。

      本例中,將對存儲過程MyPro1的EXECUTE權限賦給數據庫角色MyRole1,代碼以下:

       GRANT EXECUTE ON OBJECT::dbo.MyPro1 TO MyRole1;

      這樣,角色MyRole1就包含了對存儲過程MyPro1的執行權限。

      對於架構級安全對象,權限的收回(REVOKE)、拒絕(DENY)與權限的授予(GRANT)的方法是同樣的,具體使用時只需將GRANT改成REVOKE或DENY便可。

【例子】  對於例12.25中給MyRole1授予的對dbo.MyPro1的EXECUTE權限,可用下列語句將其收回:

     REVOKE EXECUTE ON OBJECT::dbo.MyPro1 TO MyRole1;

 

 

 

相關文章
相關標籤/搜索