Eu tenho um papel com executar no esquema, e um usuário que deve ser capaz de executar todos os procedimentos que ele vê (sob esse esquema), mas esses procedimentos estão usando tabelas / vistas a partir do banco de dados separado que esse usuário não deve ser capaz de ver.
Aqui está a solução de trabalho , mas somente se todos os componentes (tabela e procedimento) estão no mesmo banco de dados, e com consultas de este link eu sei que não há qualquer acesso negado para o usuário / papel:
Talvez haja alguma configuração papel que devo usar? Abaixo há exemplo básico que eu quero alcançar:
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];
Quase lá. Duas questões pequenas. Primeiro, você tem que explicitamente configurar o encadeamento de propriedade entre bancos de dados . É desativado por padrão. O segundo é que você tem que logon impersonate de hero1, não o usuário do banco de dados. hero1 o principal banco de dados (usuário) não tem acesso a outro banco de dados. hero1 o servidor principal (login) faz. assim
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];