首页 > 解决方案 > 创建查看查看结果的权限,无需访问其背后的表

问题描述

我正在尝试在 MSSQL2008 中创建一个视图,该视图提供系统表中的一些特定详细信息,因为该视图的用户本身无权访问系统表。有没有办法允许他们通过视图查看该数据,但不能直接从表中访问它?就像给视图一个特定的用户来执行,不管谁在调用视图(假设该用户有权从视图中选择)。

我找到了从视图中选择的权限,从表中选择,但不是我正在寻找的中间。

标签: sql-server

解决方案


正如我所提到的(在我已删除的评论中),只要 2 个对象(在本例中为TABLEand VIEW)具有相同的所有者,那么USER使用该对象的对象可以使用所有权链接。因此,如果可以从USER访问但不能从 访问,当他们查询时,他们将被授予能够查询表的隐式权限,因为它们归同一个用户所有。SELECTVIEWTABLEVIEW

这种链接可以在之后继续。例如,aPROCEDURE引用 a VIEW,引用 3 TABLEs,然后INSERTs 进入 4th。USER可能仅有权使用,PROCEDURE但如果所有对象都属于同一人USER,则权限将隐式授予两者SELECTINSERT在 的上下文中PROCEDURE

这在文档中有更详细的解释。

作为一个简单的示例,请参见下面的内容,尽管基础表上有明确的说明,但用户SomeUser成功地SELECT从. 在这种情况下,在我的实例中,两个对象都归用户所有:VIEWDENYdbo

--Create table
CREATE TABLE dbo.SomeTable (SomeID int IDENTITY,
                            SomeDate datetime DEFAULT GETDATE());
GO
--Some Rows
INSERT INTO dbo.SomeTable
DEFAULT VALUES;
GO 25
--Create view
CREATE VIEW dbo.SomeView AS
    SELECT SomeDate
    FROM dbo.SomeTable;
GO
--See Owners
SELECT o.[name] AS ObjectName, dp.[name] AS OwningUser
FROM sys.objects o
     JOIN sys.schemas s ON s.schema_id = o.schema_id
     JOIN sys.database_principals dp ON o.principal_id = dp.principal_id
                                     OR (o.principal_id IS NULL AND s.principal_id = dp.principal_id)
WHERE o.[name] IN (N'SomeTable','SomeView');
GO
--Create User
CREATE USER SomeUser WITHOUT LOGIN;
GO
--Grant SELECT on View, DENY on Table
GRANT SELECT ON dbo.SomeView TO SomeUser;
DENY SELECT ON dbo.SomeTable TO SomeUser;
GO
--Switch User Context
EXECUTE AS USER = 'SomeUser';
GO
--Run Select
SELECT *
FROM dbo.SomeView;
GO
--Revert context
REVERT
GO
--Clean up
DROP USER SomeUser;
DROP VIEW dbo.SomeView;
DROP TABLE dbo.SomeTable;

推荐阅读