DbCreator 角色可以恢复数据库但不能在 MSSQL Server 中访问它

DbCreator role can restore a database but not then access it in MSSQL Server

我正在开发一种工具,该工具具有恢复 MSSQL 数据库的恢复命令。到目前为止,该工具正在使用系统管理员权限恢复数据库。但是,根据新要求,我想最小化此命令的访问权限,即恢复应该使用 dbcreator 角色而不是 sysadmin 来完成。使用 dbcreator 我可以恢复数据库,但是此命令还会对恢复的数据库执行一些 post 操作,即更新 table 中的某些值。 Post-操作因缺少访问权限而失败,因为此用户需要 db_owner。如何在 运行 时将 db_owner 授予当前用户(dbcreator)非系统管理员的恢复数据库我的恢复命令与 post-operation 一起成功。

遵循最小权限安全原则和role-based 访问控制的一种方法是将需要提升权限的T-SQL 命令封装在存储过程中。然后可以使用证书对 proc 进行签名以授予额外的权限,而无需将这些权限直接授予用户。只需要对签名存储过程的执行权限,授权用户仅限于封装的功能。

下面是使用此技术创建存储过程和 DBRestore 角色的示例脚本。如果您的实际 RESTORE 命令包含无法参数化的选项(例如 WITH MOVE 文件位置),您需要在 proc 中使用动态 SQL 并特别注意确保从可信来源获得的验证值 and/or(例如配置 table 而不是 ad-hoc 参数值)。

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;
GO