如何判断SQL Server用户是否可以查看数据库中的每个表

时间:2011-01-07 20:15:12

标签: sql-server

我有一个应用程序,允许用户浏览SQL数据库中的数据,我想警告用户他们是否没有权限查看每个表。我通过在sys.objects上执行SELECT来获取表的列表,但是如果用户没有对表的SELECT权限,则它不会显示在该查询中,所以我无法看到知道我不知道的。

我甚至不需要知道我特别缺少什么,只要用户无法查看任何。有人知道如何做到这一点吗?

澄清:

我正在创建一个可以针对任何SQL Server运行的工具,所以我不打算设置权限来查看每个对象 - 我只是想知道当前用户是否可以。如果他们没有权利,那很好 - 我只是想确保他们知道,因为他们得到的结果不会反映整个数据库。

2 个答案:

答案 0 :(得分:1)

我不确定这是否符合您的任何安全问题,但我的想法是创建一个名为SELECT_ALL的用户,该用户对所有表具有选择权限,使用SELECT_ALL创建连接并查询sys。对象表,传递表的列表(或只是一个计数(*),如果你想知道用户是否具有完全访问权限或任何不完整的访问权限),关闭连接,然后重复用户的凭据并进行比较。

答案 1 :(得分:1)

您需要使用具有可以看到该批次的不同权限的用户来屏蔽sys.objects查询。最佳方式是视图中的EXECUTE AS OWNER或udf。这列举了所有对象(如果dbo拥有所有内容),从而允许您找出丢失的内容(由metadata visibility掩盖)

CREATE VIEW dbo.mymask
WITH EXECUTE AS OWNER --the magic
AS
SELECT * FROM sys.objects
GO

SELECT 
   *
FROM
   dbo.mymask v
   LEFT JOIN
   sys.objects o2 ON v.object_id = o.object_id

如果您使用角色,或者希望在某个角色中使用角色,那么

CREATE VIEW dbo.mymask
WITH EXECUTE AS OWNER --the magic
AS
SELECT ...
FROM
   sys.objects O
   JOIN
   sys.database_permissions DP ON ...     --premissions
   JOIN
   sys.database_principals R ON DP. = R  --role
   etc to role members etc
WHERE
   xxx.name = ORIGINAL_LOGIN()
GO