SQL Server:仅允许在某些存储过程上执行的权限

时间:2018-04-18 14:30:49

标签: sql sql-server tsql sql-server-2008-r2

我之前已经说过,我从来没有负责数据库安全,这对我来说真的很新,所以请原谅这个问题是不是很糟糕 - 我会尝试一下提供尽可能多的信息。在我的具体问题上,我没有详细搜索过。

我使用的是SQL Server 2008 R2数据库,并且我需要能够限制所有域用户在显式定义时只能执行某些存储过程。如同,DENY在所有数据库表/视图/存储过程中选择/更新/删除/等,除了显式定义的一些存储过程(将存储过程的执行授予USER(下面的域用户))。

我认为这对于服务器角色来说非常简单,但似乎自定义服务器角色仅在SQL Server 2012及更高版本中可用,并且公共服务器角色授予对我所有表的select访问权限。我读到deny总是优先于grant,所以我设置了一个数据库角色,其中select select设置为deny,但是用户仍然能够查询表。

以下是我在1台服务器上的当前设置,其中包含2个数据库:

服务器级别:

  • 登录:[域用户] - AD组登录,以便所有用户都可以连接到服务器。服务器角色是Public。

数据库级别:

  • 用户:[域用户] - AD组,以便所有用户都可以连接到数据库。
  • 数据库角色:[SP_Reader] - [域用户]作为角色成员。 Securables我将所有表设置为拒绝访问select和我的存储过程,我希望用户执行set以在执行时授予。

问题是用户仍然可以从我的表中进行选择,就好像权限不存在一样。知道我在这里做错了吗?

1 个答案:

答案 0 :(得分:0)

问题原来是除了我的自定义数据库角色(SP_Reader)之外,还为数据库用户分配了“db_datareader”角色,该角色仅提供对某些存储过程的执行。

'db_datareader'角色没有引起注意,因为我查询了'sys.database_permissions',它没有显示隐式授予的权限。

我最终找到了这个Microsoft link,它提供了一个返回所有数据库角色成员的查询:

SELECT DP1.name AS DatabaseRoleName,   
   isnull (DP2.name, 'No members') AS DatabaseUserName   
 FROM sys.database_role_members AS DRM  
 RIGHT OUTER JOIN sys.database_principals AS DP1  
   ON DRM.role_principal_id = DP1.principal_id  
 LEFT OUTER JOIN sys.database_principals AS DP2  
   ON DRM.member_principal_id = DP2.principal_id  
WHERE DP1.type = 'R'
ORDER BY DP1.name;

或者,此内部存储过程返回您作为参数传递的角色的结果:

EXEC sp_helprolemember 'db_datareader';