如果希望用户从视图中进行选择,为什么要授予该表?“撤销”是指明确撤销/拒绝吗?拒绝将覆盖授予,因此存在您的问题...您应该能够通过向视图添加授予而不对表进行任何操作来实现此目的。
这是一个简单的示例,其中SELECT
未在表上显式授予它,而是在视图上。用户可以从视图中选择,但不能从表中选择。
CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v
AS
SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;
请注意,这假定foo
未通过对架构或数据库的显式权限或角色或组成员身份授予提升的特权。
由于您正在多个数据库中使用表(很抱歉,我最初错过了第一句话的结尾),因此您可能还需要在视图不存在的数据库中的表上进行显式授予。为了避免授予对表的选择权,您可以在每个数据库中创建一个视图,然后将这些视图联接起来。
创建两个数据库和一个登录名:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
在database中d1
,创建一个用户,然后创建一个表和一个针对该表的简单视图。仅将选择授予用户视图:
USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO
现在,在第二个数据库中,创建用户,然后创建另一个表和一个视图,该视图将该表连接到中的视图d1
。仅将选择授予视图。
USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
SELECT v1.id FROM dbo.t2
INNER JOIN d1.dbo.v1 AS v1
ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO
现在启动一个新的查询窗口,并将凭据更改为登录名blat
(EXECUTE AS
此处不起作用)。然后从任一数据库的上下文中运行以下命令,它应该可以正常工作:
SELECT id FROM d1.dbo.v2;
这些都应产生Msg 229错误:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
结果:
消息229,级别14,状态5,第1行
,对对象't1',数据库'd1',模式'dbo'的SELECT权限被拒绝。
消息229,级别14,状态5,第3行
,对对象't2',数据库'd2',模式'dbo'的SELECT权限被拒绝。