我正在开发一个工具,它具有恢复MSSQL数据库的命令。到目前为止,工具还在用sysadmin权限恢复数据库。但是,根据新的要求,我希望最小化此命令的访问权限,即恢复应该使用dbcreator角色,而不是sysadmin。使用dbcreator,我能够恢复数据库,但是这个命令也对恢复的数据库执行一些后期操作,即更新表中的一些值。由于该用户需要db_owner,因此后操作失败,缺乏访问权限。如何将db_owner授予在运行时不是sysadmin的还原数据库上的当前db_owner,以便使我的restore命令与后续操作一起成功。
发布于 2020-08-19 10:26:38
遵循最小权限和基于角色的访问控制的安全原则的一种方法是封装存储过程中需要提升权限的to命令。然后,您可以使用证书对proc进行签名,以授予其他权限,而无需直接将这些权限授予用户。只有对签名存储过程的执行权限是必需的,授权用户仅限于封装的功能。
下面是一个使用此技术创建存储过程和DBRestore角色的示例脚本。如果实际的RESTORE命令包含不能参数化的选项(例如,WITH MOVE文件位置),则需要在proc中使用动态SQL,并特别注意确保验证和/或从可信源获得的值(例如配置表而不是即席参数值)。
USE master
GO
--create certificate in master database
CREATE CERTIFICATE sysadmin_cert_login_cert
ENCRYPTION BY PASSWORD = '<cert-password>'
WITH SUBJECT = 'For sysadmin privileges';
GO
--create login from certificate
CREATE LOGIN sysadmin_cert_login FROM CERTIFICATE sysadmin_cert_login_cert;
--confer sysadmin permissions to certificate login
ALTER SERVER ROLE sysadmin
ADD MEMBER sysadmin_cert_login;
GO
--create role for restore user(s)
CREATE ROLE DBRestoreRole;
GO
--create restore proc in master database
CREATE PROC dbo.usp_RestoreDatabase
@DatabaseName sysname
, @BackupFilePath varchar(255)
AS
BEGIN TRY
RESTORE DATABASE @DatabaseName FROM DISK=@BackupFilePath WITH REPLACE;
--after restore, set database owner as desired
ALTER AUTHORIZATION ON DATABASE::RestoreTest TO sa;
--execute post restore DML
UPDATE RestoreTest.dbo.SomeTable
SET SomeColumn = 1;
END TRY
BEGIN CATCH
THROW;
END CATCH;
GO
--grant execute permission to DBRestoreRole
GRANT EXECUTE ON dbo.usp_RestoreDatabase TO DBRestoreRole;
--sign proc with sysadmin certificate
ADD SIGNATURE TO dbo.usp_RestoreDatabase BY CERTIFICATE sysadmin_cert_login_cert WITH PASSWORD='<cert-password>';
--optionally, remove ephemoral private key after signing
ALTER CERTIFICATE sysadmin_cert_login_cert REMOVE PRIVATE KEY;
GO
--create example DBRestoreRole login/user
CREATE LOGIN RestoreTestLogin WITH PASSWORD = '<login-password>';
CREATE USER RestoreTestLogin;
ALTER ROLE DBRestoreRole
ADD MEMBER RestoreTestLogin;
GO
--test execution
EXECUTE AS LOGIN = 'RestoreTestLogin';
GO
EXEC dbo.usp_RestoreDatabase
@DatabaseName = N'RestoreExample'
, @BackupFilePath = 'E:\BackupFiles\RestoreExample.bak';
GO
REVERT;
GOhttps://stackoverflow.com/questions/63466149
复制相似问题