Sql-Server
使用數據庫 B 中的過程在數據庫 A 上創建使用者(使用 EXECUTE AS)
我有 2 個登錄名:
- LoginA:角色 dbcreator + 連接任何數據庫
- LoginB:角色系統管理員
我有 2 個數據庫:
- dbA:每個人都擁有它的所有權利
- dbB:只有 LoginB 對其擁有權限,LoginA 只是該數據庫的所有者,但沒有更多
我想知道是否可以從 dbA 的儲存過程在 dbB 中創建一個使用者(連結到 LoginA)。
考慮到這個儲存過程必須由 LoginA 執行。
也許某種“EXECUTE AS”機制可以提供幫助?
我也有關於如何使用“USE”的問題
$$ dbB $$" 在儲存過程中。 該解決方案可以進行一些權限修改,
但這些不能賦予 securityadmin 或 sysadmin 角色。
這是目前所做的,但顯然還有很多調試和功能要做,但我想做的精神在這裡:
CREATE PROCEDURE [dbB_UserAfterRestore] AS BEGIN SET NOCOUNT ON; USE [dbB] CREATE USER [HOSTNAME\LoginA] FOR LOGIN [HOSTNAME\LoginA] ALTER ROLE [db_datareader] ADD MEMBER [HOSTNAME\LoginA] ALTER ROLE [db_datawriter] ADD MEMBER [HOSTNAME\LoginA] END GO
由於
LoginA
不是sysadmin
伺服器角色的成員,登錄必須需要IMPERSONATE
權限才能使用EXECUTE AS
ieUSE dbB; CREATE USER LoginA for login LoginA; -- This will create user under "public" database role GRANT IMPERSONATE ON USER::LoginB to LoginA; -- This is required to use "EXECUTE AS"
獲得IMPERSONATE訪問權限後,您可以在獲得完全訪問權限 (db_owner)的位置
LoginA
創建如下過程dbA``LoginA
use dbA go CREATE PROCEDURE [UserAfterRestore] @TargetDBName varchar(128), @GranteeLogin varchar(128), @ExecuteAs varchar(128) AS BEGIN SET NOCOUNT ON; Declare @TSQL varchar(2000); SELECT @TSQL = 'USE [' + @DBName + ']; Execute as user = '''+ @ExecuteAs +'''; IF NOT EXISTS (SELECT name FROM SYS.database_principals WHERE name = '''+ @GranteeLogin +''') BEGIN CREATE USER [' + @GranteeLogin + '] FOR LOGIN ['+ @GranteeLogin + ']; END ALTER ROLE [db_datareader] ADD MEMBER ['+ @GranteeLogin +']; ALTER ROLE [db_datawriter] ADD MEMBER ['+ @GranteeLogin +'];' Print 'Executing: ' + @TSQL EXEC (@TSQL); END GO
呼叫流程如下:
exec dbA.dbo.[UserAfterRestore] @TargetDBName = dbB, @GranteeLogin = 'LoginA', @ExecuteAs = 'LoginB';
如果目標是多個數據庫,則
LoginA
必須是sysadmin
伺服器角色的成員或必須是所有數據庫的使用者(在公共角色下),並且在各個數據庫上授予 IMPERSONATEdb_owner