使用来自不同数据库的 SELECT 执行过程,没有对该不同数据库的读/写权限

Posted

技术标签:

【中文标题】使用来自不同数据库的 SELECT 执行过程,没有对该不同数据库的读/写权限【英文标题】:Execute Procedure with SELECT from different database, without read/write rights on that different database 【发布时间】:2020-04-01 15:02:04 【问题描述】:

我有一个在架构上执行的角色,并且一个用户应该能够执行他看到的每个过程(在该架构下),但是这些过程正在使用来自单独数据库的表/视图,该用户不应该能够去看看。

Here is working solution 仅当所有组件(表和过程)都在同一个数据库中,并且查询from this link我知道用户/角色没有任何拒绝访问:

也许我应该使用一些角色设置?下面是我想要实现的基本示例:

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】:

差不多了。两个小问题。首先,您必须explicitly configure cross-database ownership chaining。默认情况下它是关闭的。其次是你必须冒充 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];

【讨论】:

以上是关于使用来自不同数据库的 SELECT 执行过程,没有对该不同数据库的读/写权限的主要内容,如果未能解决你的问题,请参考以下文章

连接来自不同服务器的表

关于oracle存储过程select into 未找到数据问题

oracle 存储过程中 使用insert into Table (select) 进行数据批量添加 执行后无数据 但单独将上述insert

当我在存储过程中使用相同的公式计算日期时,日期值格式不同 - 雪花

存储过程中的“select *”如何执行?

16-查询语句的执行顺序