如何将db_owner
固定数据库角色的所有权限和特权授予应用程序角色?
精简版
命令:
GRANT CONTROL ON [DatabaseName] TO [ApplicationRoleName];
将是我想要的,但它失败了:
消息 15151,级别 16,状态 1,第 23 行
找不到对象“数据库名称”,因为它不存在或您没有权限。
研究工作
我正在调查使用 SQL Server Application Roles。
- 它就像一个用户(因为它有一个用户名和密码)
- 就像一个角色
一旦连接到服务器,您的应用程序就会运行一个存储过程来“登录”自己作为应用程序:
EXECUTE sp_SetAppRole @rolename = 'Contoso.exe', @password =
'Tm8gaSBkaWRuJ3QganVzdCBiYXNlNjQgZW5jb2RlIGEgcGFzc3dvcmQuIEl0J3Mgb25seSBhbiBleGFtcGxlIQ==';
db_owner 的权限
通常,应用程序作为db_owner固定角色成员的用户登录。该角色具有以下权限:db_owner
- 对一切
- 在每张桌子上
- 每个视图
- 每个存储过程、函数
- 对于所有现有对象
- 以及未来将存在的所有对象
同时:
- 您可以将用户放入数据库角色
- 您可以将用户置于应用程序角色中
您不能将应用程序角色放入数据库角色
那么,接下来的问题是:如何授予我的应用程序角色所有权限(即做所有事情)?
角色的权限
所以,现在是授予角色权限的时候了。按照此页面的建议:
GRANT SELECT, INSERT, UPDATE, DELETE ON Users TO [Contoso.exe];
这很有趣,但它并没有授予所有特权——它只授予SELECT
、INSERT
、UPDATE
和DELETE
. 我想授予一切——尤其是当我不知道所有特权是(或可能是)什么时。
我盲目地尝试:
GRANT ALL ON Users to [Contoso.exe];
以下出现在“消息”选项卡中:
ALL 权限已被弃用,仅为了兼容性而维护。它并不意味着在实体上定义的所有权限。
好的,所以授予ALL
并不授予所有。这……太可怕了。
所以我回到:
GRANT SELECT, INSERT, UPDATE, DELETE ON Users TO [Contoso.exe];
除了这并不能授予一切。例如,我碰巧知道有能力继续授予他人特权(具有的特权db_owner
)。所以我必须将我的声明更改为:
GRANT SELECT, INSERT, UPDATE, DELETE ON Users TO [Contoso.exe] WITH GRANT OPTION;
好的,这样更接近了,但它只适用于一张桌子。
我需要适用于所有表格的东西:
EXECUTE sp_msForEachTable 'GRANT SELECT, INSERT, UPDATE, DELETE ON ? TO [Contoso.exe] WITH GRANT OPTION;';
虽然,事实证明我错过了一些特权:
- 选择✔️
- 插入✔️
- 更新✔️
- 删除✔️
- 参考文献❌</li>
- 改变❌</li>
当然,我可以更新我的脚本:
EXECUTE sp_msForEachTable 'GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, ALTER ON ? TO [Contoso.exe] WITH GRANT OPTION;';
但是,而不是这个猫捉老鼠的猜谜游戏:我想授予所有权限。
几乎所有
在上面的警告中,SQL Server 指出ALL并不授予所有权限。但他们确实记录了所有授予的内容:
| Permission | Table | View | SP | Scalar UDF | Table UDF |
|------------|-------|------|----|------------|-----------|
| SELECT | ✔️ | ✔️ | | | ✔️ |
| INSERT | ✔️ | ✔️ | | | ✔️ |
| UPDATE | ✔️ | ✔️ | | | ✔️ |
| DELETE | ✔️ | ✔️ | | | ✔️ |
| REFERENCES | ✔️ | ✔️ | | ✔️ | ✔️ |
| EXECUTE | | | ✔️ | ✔️ | |
| ALTER | ❌ | ❌ | ❌ | ❌ | ❌ |
控制所有权限
原来他们都被骗了。为创建另一个权限。一项统治他们的权限:
- 控制
授予受让人类似所有权的能力。被授权者实际上拥有对安全对象的所有已定义权限。已被授予 CONTROL 的主体也可以授予对安全对象的权限。由于 SQL Server 安全模型是分层的,因此特定范围内的 CONTROL 隐式包含对该范围内所有安全对象的 CONTROL。例如,对数据库的 CONTROL 意味着对数据库的所有权限、对数据库中所有程序集的所有权限、对数据库中所有架构的所有权限以及对数据库内所有架构内对象的所有权限。
他们继续枚举当您拥有CONTROL时隐含的权限:
- 改变
- 控制
- 删除
- 执行
- 插入
- 收到
- 参考
- 控制
- 取得所有权
- 更新
- 查看更改跟踪
- 查看定义
那好多了。而不必知道所有的权限,我只授予一个。我不知道哪些权限适用于哪些类型的对象,我只授予一个。因为这条线:
已被授予 CONTROL 的主体也可以授予对安全对象的权限。
我不必GRANT
WITH GRANT
:
-- when you have CONTROL you also get WITH GRANT for free
EXECUTE sp_msForEachTable 'GRANT CONTROL ON ? TO [Contoso.exe];';
对所有对象
我的问题是我需要为数据库中的每个对象授予 CONTROL 权限。并且无论何时添加任何新对象,我都必须确保返回并将其添加到应用程序角色中。
我需要的是微软暗示的东西:
例如,对数据库的 CONTROL 意味着对数据库的所有权限、对数据库中所有程序集的所有权限、对数据库中所有架构的所有权限以及对数据库内所有架构内对象的所有权限。
CONTROL
重申一下,如果您授予数据库,那么您将拥有所有权限:
- 在数据库上
- 所有对象
- 数据库中的所有程序集
- 所有模式
这就是我想要的。我想将数据库GRANT CONTROL
权限授予应用程序角色:Grobber
[Contoso.exe]
GRANT CONTROL ON Grobber TO [Contoso.exe];
Msg 15151, Level 16, State 1, Line 23
Cannot find the object 'Grobber ', because it does not exist or you do not have permission.
我可能几乎解决了我的问题,只是停在 1 码线。
或者,我可能不在附近。所以我问:
如何将 db_owner 权限授予另一个角色?
编辑:警告:不要使用应用程序角色 - 它会破坏一切
当您的客户端登录到应用程序角色时,该身份是该连接的持久属性。并且使用连接池(在 ADO.net、ADO 和 ODBC 中是首选和默认选项),即使在您关闭连接之后,连接也会长时间保持打开状态。
当您的应用程序(即网络服务器)尝试打开一个新连接时,它会从连接池中获取一个。SqlConnection所做的第一件事是尝试将连接状态重置为默认值(使用sp_reset_connection
)。
尝试做的一件事是撤销您是应用角色用户sp_reset_connection
的事实。这是不允许的(因为服务器不知道你以前是谁)。因此,通过使用应用程序角色,当您尝试连接到服务器时会突然出错。
“修复”它的唯一方法是禁用连接池。
这是你不想做的事情。
因此解决方案是不在生产环境中使用应用程序角色。