Выполнить процедуру с помощью SELECT из другой базы данных, без прав на чтение / запись для этой другой базы данных - PullRequest
1 голос
/ 01 апреля 2020

У меня есть роль с execute на схеме и пользователь, который должен иметь возможность выполнять каждую процедуру, которую он видит (под этой схемой), но эти процедуры используют таблицы / представления из отдельной базы данных, которые этот пользователь не должен иметь возможность чтобы увидеть.

Здесь работает решение , но , только если все компоненты (таблица и процедура) находятся в одной базе данных и с запросами по этой ссылке Я знаю, что нет никакого запрещенного доступа для пользователя / роли:

Может быть, есть какая-то настройка роли, которую я должен использовать? Ниже приведен пример, который я хочу достичь:

USE [master];
GO
CREATE DATABASE [temporary1];
CREATE DATABASE [temporary2];
CREATE LOGIN [hero1] WITH PASSWORD = 'batman', CHECK_POLICY = OFF;

---------------

USE [temporary1];
GO
CREATE USER [hero1] FROM LOGIN [hero1];
CREATE TABLE [dbo].[test_table] ([id] INT);
INSERT [dbo].[test_table] VALUES(1);

---------------

USE [temporary2];
GO
CREATE USER [hero1] FROM LOGIN [hero1];

---------------

CREATE PROCEDURE [dbo].[inter_database_secret]
AS
BEGIN
    SELECT [id] FROM [temporary1].[dbo].[test_table];
END

---------------

GRANT EXECUTE ON [temporary2].[dbo].[inter_database_secret] TO [hero1]

---------------

EXECUTE AS USER = 'hero1';
GO
EXECUTE [temporary2].[dbo].[inter_database_secret];  --<---- Sad Error Here
REVERT;

---------------

USE [master];
GO
DROP DATABASE [temporary1];
DROP DATABASE [temporary2];
DROP LOGIN [hero1];

1 Ответ

1 голос
/ 01 апреля 2020

Почти нет. Две маленькие проблемы. Во-первых, вам необходимо явно настроить цепочку владения несколькими базами данных . По умолчанию он выключен. Во-вторых, вы должны олицетворять логин hero1, а не пользователя базы данных. hero1 участник базы данных (пользователь) не имеет доступа к другой базе данных. hero1 серверный участник (логин) делает. Итак

USE [master];
GO
CREATE DATABASE [temporary1];
CREATE DATABASE [temporary2];
CREATE LOGIN [hero1] WITH PASSWORD = 'batman', CHECK_POLICY = OFF;

ALTER DATABASE [temporary1] SET DB_CHAINING ON;  
ALTER DATABASE [temporary2] SET DB_CHAINING ON;  
go

USE [temporary1];
GO
CREATE USER [hero1] FROM LOGIN [hero1];
CREATE TABLE [dbo].[test_table] ([id] INT);
INSERT [dbo].[test_table] VALUES(1);

---------------

USE [temporary2];
GO
CREATE USER [hero1] FROM LOGIN [hero1];

go

CREATE PROCEDURE [dbo].[inter_database_secret]
AS
BEGIN
    SELECT [id] FROM [temporary1].[dbo].[test_table];
END

go

GRANT EXECUTE ON [temporary2].[dbo].[inter_database_secret] TO [hero1]

go
use [temporary2]
go
EXECUTE AS login = 'hero1';
  EXECUTE [dbo].[inter_database_secret];  --<---- Happy Result Here
REVERT;

go

USE [master];
GO
DROP DATABASE [temporary1];
DROP DATABASE [temporary2];
DROP LOGIN [hero1];
...