有没有一种方法可以让开发人员在不给他们创建用户或函数的选项的情况下授予用户对对象的权限?
我正在尝试限制开发人员的权限,我最近发现开发人员db_owner
在开发和生产环境中拥有权限!所以我正在尽我所能阻止这种疯狂。
关于这个问题的任何好文章?
有没有一种方法可以让开发人员在不给他们创建用户或函数的选项的情况下授予用户对对象的权限?
我正在尝试限制开发人员的权限,我最近发现开发人员db_owner
在开发和生产环境中拥有权限!所以我正在尽我所能阻止这种疯狂。
关于这个问题的任何好文章?
您可以让他们成为“db_securityadmin”数据库角色的成员
如前所述,如果有人可以分发权限,他们可以将权限分发给自己(或虚拟帐户)。我不确定 SQL Server 中是否有提供“给用户权限比我少”的技巧。
我会这样做的方式是使用存储过程。
创建一个存储过程,为指定用户提供特定权限或一组权限(这些权限是允许普通用户拥有的权限)。然后给开发人员执行访问这个存储过程的权限。实际上,您使用存储过程来创建有限版本的 GRANT,同时将完整的 GRANT 命令留给自己。
如果有人可以给别人权限,他也可以给自己权限做他想做的事。那么这有什么好处呢?可能我不明白你的情况。
对象的所有者可以授予对这些对象的权限。如果您的开发人员不需要授予诸如 CREATE TABLE 权限之类的东西,您也许可以向他们授予您希望他们授予权限的对象的所有权。
正如 Stefan 所说,授予他们授予权限将有效地授予他们所有权限,因为如果他们想做某事,他们所要做的就是授予自己执行此操作的权限。
不过,与其将开发人员视为敌人,不如考虑为开发人员提供第二个用于管理数据库的用户帐户。至少在他们的开发帐户上,不给开发人员任何生产权限是很常见的。
可以使用“GRANT EXECUTE ON . to ;”来完成对存储过程等对象的设置权限。
但是,您可能还想在登录和用户级别授予安全权限。您将只想确定和授予需要访问(例如执行)的对象的必要权限。考虑使用“EXECUTE AS”功能,它可以模拟另一个用户来验证执行代码所需的权限,而不必授予所有底层对象(例如表)的所有必要权限。EXECUTE AS 可以添加到存储的过程、函数、触发器等。
在存储过程中添加如下代码:CREATE PROCEDURE dbo.MyProcedure WITH EXECUTE AS OWNER
在这种情况下,您将冒充被调用模块的所有者。您还可以冒充 SELF,或者创建或更改模块的用户,或者...冒充 CALLER,这将使模块能够获得当前用户的权限,或者...冒充 OWNER,这将获得被调用的过程的所有者 OR... 模拟 'user_name',它将模拟特定用户 OR... 模拟 'login_name' with 将模拟特定登录。
大多数时候,您只需要授予存储过程的执行权限,然后将权限授予存储过程中引用的所有对象。
通过这种方式,您无需授予隐式权限(例如:更新数据或调用其他 procs)。所有权链为您处理这个问题。这对于动态 sql 或您需要创建提升的安全任务(例如 CREATE TABLE)特别有用。EXECUTE AS 是一个方便的工具来考虑这些。
这个例子可能有助于澄清所有这些:
创建一个名为 NoPrivUser 的用户,该用户具有对数据库的公共访问权限(例如 dbadb)
USE [master] GO CREATE LOGIN [NoPrivUser] WITH PASSWORD=N'ABC5%', DEFAULT_DATABASE=[dbadb], CHECK_EXPIRATION=ON, CHECK_POLICY=ON GO USE [DBAdb] GO CREATE USER [NoPrivUser] FOR LOGIN [NoPrivUser] GO
注意:此过程的创建者或所有者将需要在目标数据库中创建表权限。
使用 DBAdb go CREATE PROCEDURE dbo.MyProcedure WITH EXECUTE AS OWNER AS IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].MyTable') 并输入 (N'U')) 创建表 MyTable (PKid int, column1 char(10)) INSERT INTO MyTable VALUES (1,'ABCDEF')
去
将 dbo.MyProcedure 上的 EXEC 授予 NoPrivUser;去
-- 现在以 NoPrivUser 身份登录到您的数据库服务器并运行以下命令。
使用 dbadb 去
执行 dbo.MyProcedure
(1 行受影响)
现在尝试在以 NoPrivuser 身份登录时从新表中进行选择。
您将获得以下信息:
从 MyTable 中选择 *
消息 229,级别 14,状态 5,第 1 行对象“MyTable”、数据库“DBAdb”、模式“dbo”的 SELECT 权限被拒绝。
这是意料之中的,因为您仅在以 NoPrivUser 身份登录时在 Owner 的安全上下文中运行了该过程。NoPrivUser 没有实际读取表的权限。只是为了执行创建和插入行的过程。
使用 EXECUTE AS 子句,存储过程在对象所有者的上下文中运行。此代码成功创建 dbo.MyTable 并成功插入行。在此示例中,用户“NoPrivUser”绝对没有授予修改表或读取或修改此表中的任何数据的权限。它仅具有完成此过程上下文中编码的特定任务所需的权限。
这种创建存储过程的方法非常有用,该存储过程可以执行需要提升的安全权限而无需永久分配这些权限的任务。
我发现 db_owner 角色最危险的方面是,如果您对某个权限发出拒绝,那么该角色的成员可以将其授予他们自己。我刚刚开始阅读这个,我正在测试这个
Create role db_ControlDatabase
grant control to db_ControlDatabase
deny backup database to db_ControleDatabase
alter role db_ControlDatabase add member TestUser
到目前为止,我发现该主题TestUser
具有权限,但无法添加或删除固定数据库角色的成员。此时您应该能够拒绝您需要的任何内容,例如备份证书、备份主密钥等。
以下是可以拒绝或授予的权限列表: