【问题标题】:How to restrict user access to tables, but not to SPs and Views in SQL Server 2008如何限制用户访问表,但不限制 SQL Server 2008 中的 SP 和视图
【发布时间】:2017-03-08 07:32:56
【问题描述】:

先决条件:

假设我有 2 张桌子。

  1. 表 A 包含 A、B 和 C 列。

  2. 包含 A、B 和 C 列的表 B。

我还有一个存储过程来更新两个表 我有一个简单的视图来连接表格。

我也有一个用户,我们就叫他……“Bob”。

问题:

现在;

我希望“Bob”只能访问视图和存储过程。 “Bob”无法读取/写入任一表,只能读取视图和存储过程。

我将如何实现这一目标?

【问题讨论】:

  • 您授予对存储过程的执行权限,对视图的选择权限,并拒绝对表的所有权限。我没有 sql server 来检查这个,但它应该是这样的
  • @ZoharPeled 这不起作用。你会得到一个例外,说在桌子上缺少读/写。 - 这正是我问这个问题的原因:)
  • 这是解决您问题的关键:msdn.microsoft.com/en-us/library/ms188354.aspx(存储过程代码中的 EXECUTE AS 子句)。基本上,您可以让它以存储过程的所有者身份执行(我假设它对基础表具有权限)。
  • @MK_ 我猜以上内容不适用于视图?
  • 对于视图,您只需授予视图的 SELECT 权限,即使不授予底层对象权限,用户也应该能够从视图中选择(而不能从底层表中选择) /views)。

标签: sql-server sql-server-2008 stored-procedures view permissions


【解决方案1】:

老问题,但 SQL 中的所有权链接是答案。该问题的 cmets 有 SP 问题的答案,但 OP 暗示针对视图运行 select 存在问题。

对于SP,需要指定execute as owner子句

CREATE PROCEDURE dbo.YourProc
WITH EXECUTE AS OWNER
AS
   --Your code here
GO

GRANT EXEC ON dbo.YourProc TO Bob;
GO

如果 SP 的所有者有权访问这些表,这将起作用。

对于视图,同样的想法。我绊倒了,因为我创建了一个新的视图/模式来限制访问,我给了用户对视图的选择权限,但是模式的所有者没有访问基础表的权限,所以当用户执行选择时,我得到了一个关于没有权限对基础表运行选择的错误。将架构的所有者更改为 dbo(拥有表)为我解决了这个问题。

我编写了一个脚本来稍微展示一下,并为用户提供架构上的选择权限,而不仅仅是视图(我知道这不是他们想要的唯一视图)

DECLARE @Schema varchar(128) = 'Reporting', @Username varchar(255) = 'ReportingUser', @dbName varchar(255)

SELECT @dbName=db_name(dbid) FROM master.dbo.sysprocesses WHERE spid=@@spid

IF NOT EXISTS (SELECT * FROM master.sys.server_principals where name = @Username)
BEGIN
    Print 'User must be created/added to SQL before being given database permissions'
    GOTO TheEnd
END

IF NOT EXISTS (SELECT * FROM sysusers where name = @Username)
BEGIN
    EXEC sp_grantdbaccess @Username,@Username
END

IF NOT EXISTS (SELECT * FROM sys.schemas WHERE name = @SCHEMA)
BEGIN
    EXEC('CREATE SCHEMA ' + @Schema)
END

EXEC ('ALTER USER '+@Username+' WITH DEFAULT_SCHEMA = ' + @Schema)

EXEC ('GRANT SELECT ON SCHEMA :: '+ @Schema +' TO '+ @Username)

TheEnd:

为了避免一些人在这个问题上也有一些问题,这里有一些有用的查询来识别和解决所有权问题:

SELECT s.name AS SchemaName, 
       s.schema_id, 
       u.name AS schema_owner
FROM sys.schemas s
     INNER JOIN sys.sysusers u ON u.uid = s.principal_id
ORDER BY s.name;

这将显示架构所有者

exec sp_tables @table_type = "'table', 'view'"

这将显示视图/表的所有者

【讨论】:

  • 太棒了!很好的答案
猜你喜欢
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 2014-06-15
  • 1970-01-01
  • 2011-06-03
相关资源
最近更新 更多