Олицетворенный контекст безопасности EXECUTE AS
помещается в изолированную программную среду для текущей базы данных.Вы не можете получить доступ к другим базам данных внутри функции, если база данных не является TRUSTWORTHY
, что обычно не является хорошей практикой.
Для кросс-доступа к базе данных пользователями с минимальными привилегиями рассмотрите возможность использования подписи модуля .Это позволяет вам предоставлять доступ к другим базам данных и объектам в контексте выполнения модуля, не предоставляя конечным пользователям прямых разрешений.Пользователям нужны только разрешения для этой функции.
Ниже приведен пример сценария, подобранного из указанной статьи для вашей конкретной потребности.Хотя этот базовый метод может быть расширен для предоставления разрешений sysadmin
, рекомендуется использовать учетную запись с минимальными привилегиями.
-- Create a certificate in msdb
USE msdb;
CREATE CERTIFICATE msdb_certificate
ENCRYPTION BY PASSWORD = 'p@Ss0RDforTheceRT1cate'
WITH SUBJECT = 'For cross-database access to msdb database';
-- create a user from certification with needed permissions
CREATE USER msdb_certificate_user FROM CERTIFICATE msdb_certificate;
GRANT SELECT ON msdb.dbo.sysjobschedules TO msdb_certificate_user;
-- Copy certificate to user database (Example)
DECLARE @cert_id int = cert_id('msdb_certificate');
DECLARE @public_key varbinary(MAX) = certencoded(@cert_id),
@private_key varbinary(MAX) =
certprivatekey(@cert_id,
'p@Ss0RDforTheceRT1cate',
'p@Ss0RDforTheceRT1cate');
DECLARE @sql nvarchar(MAX) =
'CREATE CERTIFICATE msdb_certificate
FROM BINARY = ' + convert(varchar(MAX), @public_key, 1) + '
WITH PRIVATE KEY (BINARY = ' +
convert(varchar(MAX), @private_key, 1) + ',
DECRYPTION BY PASSWORD = ''p@Ss0RDforTheceRT1cate'',
ENCRYPTION BY PASSWORD = ''p@Ss0RDforTheceRT1cate'')';
EXEC YourDatabase.sys.sp_executesql @sql;
ALTER CERTIFICATE msdb_certificate REMOVE PRIVATE KEY; --remove ephemeral private key
GO
--sign module with certificate
USE YourDatabase;
ADD SIGNATURE TO dbo.MyTestFunction BY CERTIFICATE msdb_certificate
WITH PASSWORD = 'p@Ss0RDforTheceRT1cate';
ALTER CERTIFICATE msdb_certificate REMOVE PRIVATE KEY; --remove ephemeral private key
GO
--users only need permissions on directly invoked module
GRANT EXECUTE ON dbo.MyTestFunction TO YourUser;
GO