SQL Server:向视图中的用户授予选择访问权限,而不是其表中的用户

Hik*_*ari 11 schema sql-server permissions

我有一个带有几个数据库的 SQL Server 2012 实例。在其中一个中,我创建了一个视图,它选择的不仅仅是数据库中的表。

我希望用户能够选择该视图,但不能选择其表。创建视图正是因为用户无法选择表。

我已阅读/sf/ask/25789011/http://msdn.microsoft.com/en-us/library/ms188676。 aspx,但它仍然无法正常工作。

如果我GRANT SELECT TABLE TO USER对所有表执行 a ,用户就可以选择视图。但是如果我撤销到任何表,它就会失败。

这应该是一个简单的过程,但我无法让它工作。我以前见过它发生过(实例的所有者让我访问视图,但没有对它的表执行此操作)但我无法执行此操作或找到知道如何操作的人。

有人可以为我提供有关如何操作的教程或代码示例吗?


当用户SELECTs查看我收到的消息时:

对象<TABLE>、数据库<DB>、架构的 SELECT 权限被拒绝dbo

如果我授予该表的选择权,错误消息会将表名更改为视图读取的另一个表。

Aar*_*and 21

如果您希望用户从视图中进行选择,为什么要授予该表?“撤销”是指明确撤销/拒绝吗?Deny 将覆盖 grant 所以这是你的问题......你应该能够通过向视图添加授权而不在表上做任何事情来实现这一点。

这是一个快速示例,其中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;
Run Code Online (Sandbox Code Playgroud)

请注意,这假定foo尚未通过对架构或数据库的显式权限或通过角色或组成员资格授予提升的权限。

由于您在多个数据库中使用表(抱歉,我最初错过了第一句话的结尾),因此您可能还需要对不存在视图的数据库中的表进行显式授权。为了避免向表授予选择权,您可以在每个数据库中创建一个视图,然后加入这些视图。

创建两个数据库和一个登录名:

CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

现在,在第二个数据库中,创建用户,然后创建另一个表和一个将该表连接到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
Run Code Online (Sandbox Code Playgroud)

现在启动一个新的查询窗口并将凭据更改为登录blatEXECUTE AS此处不起作用)。然后从任一数据库的上下文运行以下命令,它应该可以正常工作:

SELECT id FROM d1.dbo.v2;
Run Code Online (Sandbox Code Playgroud)

这些都应该产生 Msg 229 错误:

SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Run Code Online (Sandbox Code Playgroud)

结果:

消息 229,级别 14,状态 5,第 1 行
SELECT 权限被拒绝对对象“t1”、数据库“d1”、架构“dbo”。
消息 229,级别 14,状态 5,第 3 行
对象“t2”、数据库“d2”、架构“dbo”的 SELECT 权限被拒绝。