防止修改 dbo 对象,同时允许修改其他模式

Jef*_*eff 2 sql-server permissions sql-server-2008-r2

我有一个使用 sql server (2008r2) 数据库的供应商解决方案。我们可以在我们自己的架构中做任何我们想做的事情,但不能在没有供应商许可的情况下修改 dbo 对象。我们所做的任何定制都在我们自己的模式 (cust) 中。我们可以完全控制此服务器,并且始终允许任何开发人员拥有系统管理员权限。最近,我注意到这些规则没有得到遵守,所以我想看看我是否可以首先设置权限来阻止它。

这是我想要完成的:

表:读取/写入所有,仅更改客户模式,视图设计

Views/Sprocs/Functions:查看任何定义,仅创建或更改 cust 模式

我创建了一个新用户(dev)并应用了以下内容:

deny alter on schema::dbo to dev
grant alter on schema::custom to dev
grant view definition to dev
Run Code Online (Sandbox Code Playgroud)

这会实现我想要的,还是我错过了其他东西?

解决方案(感谢 AMtwo)

use master
go
create login dev with password = 'test', check_expiration = off, check_policy = off
grant control server to dev


use CustomerDB 
go
if not exists(select * from sys.database_principals where name = 'dev') begin
    create user dev for login dev 
    grant select, insert, update, delete, execute, alter on schema::custom to dev
    grant view definition to dev
    deny alter on schema::dbo to dev
    -- deny other schemas here
end`
Run Code Online (Sandbox Code Playgroud)

AMt*_*two 9

我们可以完全控制此服务器,并且始终允许任何开发人员拥有系统管理员权限。

sysadmin特权有效地短路了任何其他权限。如果用户是sysadmin固定服务器角色的成员,则任何DENY权限都将被忽略。

您可以通过撤销sysadmin并改为使用CONTROL SERVER权限来解决此问题。CONTROL SERVERsysadmin固定服务器角色类似,不同之处在于它CONTROL SERVER会服从DENY权限。

GRANT CONTROL SERVER TO dev
EXEC sp_dropsrvrolemember 'dev', 'sysadmin'
DENY ALTER ON SCHEMA::dbo TO dev
Run Code Online (Sandbox Code Playgroud)

如果您想完全取消开发人员对服务器的高级访问权限(这是一个很好的主意),那么您可以采取两种方法:

  • 授予对数据库的广泛访问权限,然后明确拒绝对 dbo 的权限。

    USE MyDB
    GRANT SELECT,INSERT,UPDATE,DELETE,EXECUTE,ALTER ON DATABASE::MyDB TO dev
    GRANT VIEW DEFINITION TO dev
    DENY ALTER ON SCHEMA::dbo TO dev
    EXEC sp_dropsrvrolemember 'dev', 'sysadmin'
    
    Run Code Online (Sandbox Code Playgroud)
  • 明确授予用户所需的权限;不要ALTERdbo.

    USE MyDB
    GRANT SELECT,INSERT,UPDATE,DELETE,EXECUTE,ALTER ON SCHEMA::custom TO dev
    GRANT SELECT,INSERT,UPDATE,DELETE,EXECUTE ON SCHEMA::dbo TO dev
    GRANT VIEW DEFINITION TO dev
    EXEC sp_dropsrvrolemember 'dev', 'sysadmin'
    
    Run Code Online (Sandbox Code Playgroud)

最终,您希望遵循(或接近)最小特权原则。但您还必须平衡复杂性和可管理性。

我建议你创建一些测试场景来测试你作为开发者运行时的权限,这样你就可以确保用户拥有正确的权限。您可以使用EXECUTE AS LOGIN以下方法执行此操作:

EXECUTE AS LOGIN='SomeDeveloper';
CREATE TABLE custom.AM2 (foo BIT);
GO
CREATE PROCEDURE custom.GetAM2 AS SELECT * FROM custom.AM2;
GO
DROP TABLE custom.AM2;
DROP PROCEDURE custom.GetAM2;
GO
REVERT;
Run Code Online (Sandbox Code Playgroud)