SQL Server中通用資料庫角色許可權的處理詳解
阿新 • • 發佈:2020-01-09
前言
安全性是所有資料庫管理系統的一個重要特徵。理解安全性問題是理解資料庫管理系統安全性機制的前提。
最近和同事在做資料庫許可權清理的事情,主要是刪除一些賬號;取消一些賬號的較大的許可權等,例如,有一些有db_owner許可權,我們取消賬號的資料庫角色db_owner,授予最低要求的相關許可權。但是這種工作完全是一個體力活,而且是吃力不討好,而且推進很慢。另外,為了管理方便和細化,我們又在常用的資料庫角色外,新增了6個通用的資料庫角色。
如下截圖所示。
另外,為了減少授權工作量和一些重複的體力活,我們建立了一個作業,每天定期執行一個儲存過程db_common_role_grant_rigths,這個儲存過程的邏輯如下:
1:遍歷所有使用者資料庫(排除了系統資料庫以及一些特殊資料庫),發現該資料庫不存在這些通用資料庫角色,那麼就建立相關資料庫角色。
2:遍歷所有使用者資料庫,為相關資料庫角色授權,例如,如果發現某個新增的儲存過程,沒有授權給db_procedure_execute資料庫角色。那麼就執行授權操作。
當然目前還在測試、應用階段,以後會根據具體相關需求,不斷完善相關功能。
--================================================================================================================== -- ScriptName : db_common_role_grant_rigths.sql -- Author : 瀟湘隱者 -- CreateDate : 2018-09-13 -- Description : 建立資料庫角色db_procedure_execute等,並授予相關許可權給角色。 -- Note : /****************************************************************************************************************** Parameters : 引數說明 ******************************************************************************************************************** @RoleName : 角色名 ******************************************************************************************************************** Modified Date Modified User Version Modified Reason ******************************************************************************************************************** 2018-09-12 瀟湘隱者 V01.00.00 新建該指令碼。 2018-09-12 瀟湘隱者 V01.00.01 注意@@ROWCOUNT的生效範圍;解決迴圈邏輯問題。 2018-09-26 瀟湘隱者 V01.00.02 修正型別為FT(CLR_TABLE_VALUED_FUNCTION)的函式問題。程式集 (CLR) 表值函式 *******************************************************************************************************************/ --=================================================================================================================== USE YourSQLDba; GO IF EXISTS (SELECT 1 FROM sys.procedures WHERE type='P' AND name='db_common_role_grant_rigths') BEGIN DROP PROCEDURE Maint.db_common_role_grant_rigths; END GO CREATE PROCEDURE Maint.db_common_role_grant_rigths AS BEGIN DECLARE @database_id INT; DECLARE @database_name sysname; DECLARE @cmdText NVARCHAR(MAX); DECLARE @prc_text NVARCHAR(MAX); DECLARE @RowIndex INT; IF OBJECT_ID('TempDB.dbo.#databases') IS NOT NULL DROP TABLE dbo.#databases; CREATE TABLE #databases ( database_id INT,database_name sysname ) IF OBJECT_ID('TempDB.dbo.#sql_text') IS NOT NULL DROP TABLE dbo.#sql_text; CREATE TABLE #sql_text ( sql_id INT IDENTITY(1,1),sql_cmd NVARCHAR(MAX) ) INSERT INTO #databases SELECT database_id,name FROM sys.databases WHERE name NOT IN ( 'master','tempdb','model','msdb','distribution','ReportServer','ReportServerTempDB','YourSQLDba' ) AND state = 0; --state_desc=ONLINE --開始迴圈每一個使用者資料庫(排除了上面相關資料庫) WHILE 1= 1 BEGIN SELECT TOP 1 @database_name= database_name FROM #databases ORDER BY database_id; IF @@ROWCOUNT =0 BREAK; --PRINT(@database_name); -- SP_EXECUTESQL 中切換資料庫不能當引數傳入。 --建立資料庫角色db_procedure_execute SET @cmdText = 'USE ' + @database_name + ';' +CHAR(10) SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_procedure_execute'') BEGIN CREATE ROLE [db_procedure_execute] AUTHORIZATION [dbo]; END ' + CHAR(10); --建立資料庫角色db_function_execute SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_function_execute'') BEGIN CREATE ROLE [db_function_execute] AUTHORIZATION [dbo]; END' + CHAR(10); --建立資料庫角色db_view_table_definition SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_view_table_definition'') BEGIN CREATE ROLE [db_view_table_definition] AUTHORIZATION [dbo]; END ' + CHAR(10); --建立資料庫角色db_view_view_definition SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_view_view_definition'') BEGIN CREATE ROLE [db_view_view_definition] AUTHORIZATION [dbo]; END ' + CHAR(10); --建立資料庫角色db_view_procedure_definition SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_view_procedure_definition'') BEGIN CREATE ROLE [db_view_procedure_definition] AUTHORIZATION [dbo]; END ' + CHAR(10); --建立資料庫角色db_view_function_definition SELECT @cmdText += 'IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name =''db_view_function_definition'') BEGIN CREATE ROLE [db_view_function_definition] AUTHORIZATION [dbo]; END ' + CHAR(10); --PRINT @cmdText; -- EXECUTE SP_EXECUTESQL @cmdText; EXECUTE (@cmdText); --給角色db_procedure_execute授權 SET @cmdText ='USE ' + QUOTENAME(@database_name) + ';' SET @cmdText +='INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT EXECUTE ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_procedure_execute;'' FROM sys.procedures s WHERE NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_procedure_execute''))'; EXECUTE SP_EXECUTESQL @cmdText; --給角色db_function_execute(標量函式授權) SET @cmdText ='USE ' + QUOTENAME(@database_name) + ';' SET @cmdText += 'INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT EXEC ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_function_execute; '' FROM sys.all_objects s WHERE SCHEMA_NAME(schema_id) NOT IN (''sys'',''INFORMATION_SCHEMA'') AND NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id =USER_ID(''db_function_execute'') ) AND ( s.[type] = ''FN'' OR s.[type] = ''AF'' OR s.[type] = ''FS'' --OR s.[type] = ''FT'' ) ;' EXECUTE SP_EXECUTESQL @cmdText; --給角色db_function_execute(表值函式授權) SET @cmdText ='USE ' + @database_name + ';' SET @cmdText += 'INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT SELECT ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_function_execute;'' FROM sys.all_objects s WHERE SCHEMA_NAME(schema_id) NOT IN (''sys'',''INFORMATION_SCHEMA'') AND NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_function_execute'')) AND ( s.[type] = ''TF'' OR s.[type] = ''IF'' ) ; ' EXECUTE SP_EXECUTESQL @cmdText; --檢視儲存過程定義授權 SET @cmdText ='USE ' + @database_name + ';' SET @cmdText +=' INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT VIEW DEFINITION ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_view_procedure_definition;'' FROM sys.procedures s WHERE NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_view_procedure_definition''))' EXECUTE(@cmdText); --檢視函式定義的授權 SET @cmdText ='USE ' + @database_name + ';' SELECT @cmdText += 'INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT VIEW DEFINITION ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_view_function_definition;'' FROM sys.objects s WHERE type_desc IN (''SQL_SCALAR_FUNCTION'',''SQL_TABLE_VALUED_FUNCTION'',''AGGREGATE_FUNCTION'' ) AND NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_view_function_definition''))'; EXECUTE SP_EXECUTESQL @cmdText; --查看錶定義的授權 SET @cmdText ='USE ' + @database_name + ';' SET @cmdText +='INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT VIEW DEFINITION ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_view_table_definition ;'' FROM sys.tables s WHERE NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_view_table_definition''))'; EXECUTE SP_EXECUTESQL @cmdText; --檢視檢視定義的授權 SET @cmdText ='USE ' + @database_name + ';' SET @cmdText +='INSERT INTO #sql_text(sql_cmd) SELECT ''GRANT VIEW DEFINITION ON '' + SCHEMA_NAME(schema_id) + ''.'' + QUOTENAME(name) + '' TO db_view_view_definition; '' FROM sys.views s WHERE NOT EXISTS ( SELECT 1 FROM sys.database_permissions p WHERE p.major_id = s.object_id AND p.grantee_principal_id = USER_ID(''db_view_view_definition''))'; EXECUTE SP_EXECUTESQL @cmdText; WHILE 1= 1 BEGIN SELECT TOP 1 @RowIndex=sql_id,@cmdText = 'USE ' + @database_name + '; '+ sql_cmd FROM #sql_text ORDER BY sql_id; IF @@ROWCOUNT =0 BREAK; PRINT(@cmdText); EXECUTE(@cmdText); DELETE FROM #sql_text WHERE sql_id =@RowIndex END DELETE FROM #databases WHERE database_name=@database_name; END DROP TABLE #databases; DROP TABLE #sql_text; END
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對我們的支援。