Sql-Server

在可以訪問選定係統數據庫表的使用者數據庫中創建視圖

  • May 10, 2021

使用最小權限原則,我應該賦予角色“Checklist_role”什麼訪問權限,該角色對使用者數據庫“ChecklistDB”中的視圖“MaintenanceJobs_view”具有讀取權限,可以訪問 msdb 數據庫中系統表中的某些列?

以下是與我想做的類似的範例:

USE ChecklistDB;
GO
/* Create View */
CREATE VIEW [MaintenanceJobs_view]
AS
SELECT [name],
      [description],
      [enabled],
      [category_id]
FROM [msdb].[dbo].[sysjobs];
GO
/* Create Role based on principle of least privilege */
CREATE ROLE [CheckList_role];
GO
/* What permissions are required? */

這可以通過授予角色(Checklist_role)某些權限而不授予“msdb”數據庫中的任何對象權限來完成嗎?

在這個階段,主要是在非常有限的時間內展示概念證明。從長遠來看,我肯定想使用儲存過程。

這可以通過授予角色(Checklist_role)某些權限而不授予“msdb”數據庫中的任何對象權限來完成嗎?

除了視圖,您還可以使用包含查詢的多語句表值函式或儲存過程,並使用證書對模組進行簽名以授予額外權限。這允許您遵循最小權限原則,因為只需要函式或儲存過程的權限。

下面是一個範例腳本,它在兩個數據庫中創建證書以及所需的使用者和權限。

USE ChecklistDB;
GO
CREATE FUNCTION MaintenanceJobs_function()
RETURNS @table TABLE(
    name sysname
   ,description nvarchar(1024)
   ,enabled tinyint
   ,category_id int
)
AS
BEGIN
   INSERT @table
   SELECT [name],
          [description],
          [enabled],
          [category_id]
   FROM [msdb].[dbo].[sysjobs];
   RETURN;
END
GO
CREATE ROLE Checklist_role;
GRANT SELECT ON dbo.MaintenanceJobs_function TO Checklist_role;
GO

--Create self-signed cert in ChecklistDB and copy to msdb
USE ChecklistDB;
CREATE CERTIFICATE CrossDatabasePermissionsCertificate
   ENCRYPTION BY PASSWORD = 'temporary password'
   WITH SUBJECT = 'Allow cross-database access';

--Copy cert to another database.
DECLARE @cert_id int = CERT_ID('CrossDatabasePermissionsCertificate');
DECLARE @public_key  varbinary(8000) = CERTENCODED(@cert_id),
       @private_key varbinary(8000) = CERTPRIVATEKEY(@cert_id , 'temporary password', 'temporary password');

--these values should not be NULL
IF @cert_id IS NULL THROW 50000, 'Assertion failed: @cert_id is NULL', 0;
IF @public_key IS NULL THROW 50000, 'Assertion failed: @public_key is NULL', 0;
IF @private_key IS NULL THROW 50000, 'Assertion failed: @private_key is NULL', 0;

--copy certificate in target database
DECLARE @sql nvarchar(MAX) =
     'CREATE CERTIFICATE CrossDatabasePermissionsCertificate
      FROM  BINARY = ' + CONVERT(varchar(MAX), @public_key, 1) + '
      WITH PRIVATE KEY (BINARY = ' +
         CONVERT(varchar(MAX), @private_key, 1)
       + ', DECRYPTION BY PASSWORD = ''temporary password'''
       + ', ENCRYPTION BY PASSWORD = ''temporary password'');'
PRINT @sql; --show CREATE CERTIFICATE DDL

EXEC msdb.sys.sp_executesql @sql;
GO

--create certificate user in msdb and grant permissions needed by the module
USE msdb;
CREATE USER CrossDatabasePermissionsCertificateUser FROM CERTIFICATE CrossDatabasePermissionsCertificate;
GRANT SELECT ON dbo.sysjobs TO CrossDatabasePermissionsCertificateUser;
GO

--add signature to module by the same certificate that exists in both databases
USE ChecklistDB;
ADD SIGNATURE TO dbo.MaintenanceJobs_function BY CERTIFICATE CrossDatabasePermissionsCertificate WITH PASSWORD = 'temporary password';
ALTER CERTIFICATE CrossDatabasePermissionsCertificate REMOVE PRIVATE KEY;
GRANT SELECT ON dbo.MaintenanceJobs_function TO Checklist_role;
GO

--test with minimally priviliged login/user
CREATE LOGIN TestUser1 WITH PASSWORD = 'Test-Permissi0ns';
CREATE USER TestUser1;
ALTER ROLE Checklist_role
   ADD MEMBER TestUser1;
EXECUTE AS LOGIN = 'TestUser1';
SELECT * FROM dbo.MaintenanceJobs_function();
GO
REVERT;
GO

在數據庫中,您不需要授予視圖或儲存過程中包裝對象的權限,它可以工作,但是當涉及到不同的數據庫時,您需要明確授予權限。

如上所述,如果您的角色在視圖內的任何使用者定義的表上進行選擇 - 它會起作用。在上述場景中,您需要在 msdb 上授予對 sysjobs 的權限 - 這取決於您是向新角色還是現有角色授予權限。您首先需要在 msdb 中添加此角色並授予對 sysjobs 的權限。

步驟如下:

use msdb
go
CREATE ROLE [CheckList_role];
GO
grant select on sysjobs to [CheckList_role]
go

現在,任何同時分配了兩個角色(即一個輸入msbd和另一個輸入)的登錄名都ChecklistDB可以從視圖中執行選擇MaintenanceJobs_view

引用自:https://dba.stackexchange.com/questions/291161