如何将db_owner
固定数据库角色的所有权限和特权授予应用程序角色?
命令:
GRANT CONTROL ON [DatabaseName] TO [ApplicationRoleName];
将是我想要的,但它失败了:
Msg 15151, Level 16, State 1, Line 23
Cannot find the object 'DatabaseName', because it does not exist or you do not have permission.
我正在调查使用SQL Server应用程序角色。
连接到服务器后,您的应用程序运行存储过程以“登录”自身作为应用程序:
EXECUTE sp_SetAppRole @rolename='Contoso.exe', @password='Tm8gaSBkaWRuJ3QganVzdCBiYXNlNjQgZW5jb2RlIGEgcGFzc3dvcmQuIEl0J3Mgb25seSBhbiBleGFtcGxlIQ=='
通常,应用程序以db_owner固定角色成员的用户身份登录。 db_owner
角色有权限:
同时:
您不能将应用程序角色放入数据库角色
那么问题是如何授予我的应用程序角色,所有权限,以执行所有操作。
所以现在是时候授予角色权限了。按照此页面的建议:] 2
GRANT SELECT, INSERT, UPDATE, DELETE ON Users TO "Contoso.exe";
这很有意思,但并没有授予所有特权 - 它只授予SELECT
,INSERT
,UPDATE
和DELETE
。我想要给予一切 - 特别是当我不知道所有特权是什么(或可能是什么)时。
我一味地尝试:
GRANT ALL ON Users to "Contoso.exe";
The ALL permission is deprecated and maintained only for compatibility. It DOES NOT imply ALL permissions defined on the entity.
好的,所以授予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;'
虽然事实证明我错过了一些特权:
当然我可以更新我的脚本:
EXECUTE sp_msForEachTable 'GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES, ALTER ON ? TO "Contoso.exe" WITH GRANT OPTION;'
但不是这个猫捉老鼠的猜谜游戏:我想授予所有权限。
在上面的警告中,SQL Server注意到ALL不会全部授予。但他们做document what all does grant:
| Permission | Table | View | SP | Scalar UDF | Table UDF |
|------------|-------|------|----|------------|-----------|
| SELECT | ✔️ | ✔️ | | | ✔️ |
| INSERT | ✔️ | ✔️ | | | ✔️ |
| UPDATE | ✔️ | ✔️ | | | ✔️ |
| DELETE | ✔️ | ✔️ | | | ✔️ |
| REFERENCES | ✔️ | ✔️ | | ✔️ | ✔️ |
| EXECUTE | | | ✔️ | ✔️ | |
| ALTER | ❌ | ❌ | ❌ | ❌ | ❌ |
事实证明他们都被欺骗了。为另一个权限创建。一个permission to rule them all:
- 控制
赋予受让人类似于所有权的能力。被授予者有效地拥有安全性的所有已定义权限。已被授予CONTROL的委托人也可以授予对安全性的权限。由于SQL Server安全模型是分层的,因此特定范围内的CONTROL隐式包含对该范围下所有安全性的CONTROL。例如,对数据库的CONTROL表示数据库的所有权限,数据库中所有程序集的所有权限,数据库中所有模式的所有权限以及数据库中所有模式中对象的所有权限。
他们继续枚举您拥有CONTROL时隐含的权限:
那好多了。我只需要授予一个权限,而不必知道所有权限。而不是知道哪些权限适用于哪种对象,我只授予一个。因为这条线:
已被授予CONTROL的委托人也可以授予对安全性的权限。
我没有GRANT
WITH GRANT
:
EXECUTE sp_msForEachTable 'GRANT CONTROL ON ? TO [Contoso.exe];' --when you have CONTROL you also get WITH GRANT for free
我的问题是我需要为数据库中的每个对象赋予CONTROL权限。每当添加任何新对象时,我必须确保返回并将其添加到应用程序角色。
我需要的是向微软暗示的事情:
例如,对数据库的CONTROL表示数据库的所有权限,数据库中所有程序集的所有权限,数据库中所有模式的所有权限以及数据库中所有模式中对象的所有权限。
要重申,如果您在数据库上授予CONTROL
,那么您将拥有所有权限:
这就是我想要的。我希望将Grobber
数据库的GRANT CONTROL权限授予[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权限授予其他角色?
当您的客户端登录到app角色时,该标识是该连接的持久属性。并且通过连接池(ADO.net,ADO和ODBC中的首选和默认选项),即使关闭连接,该连接也会长时间保持打开状态。
当您的应用程序(即Web服务器)尝试打开新连接时,它会从连接池中获取一个连接。 SqlConnection所做的第一件事是尝试将连接状态重置为默认值(使用sp_reset_connection
)。
sp_reset_connection
试图做的事情之一就是撤消你是app角色用户的事实。这是不允许的(因为服务器不知道你以前是谁)。因此,通过使用应用程序角色,当您尝试连接到服务器时,您将突然收到错误。
“修复”它的唯一方法是禁用连接池。
这是你不想做的事情。
因此,解决方案是不在生产环境中使用应用程序角色。
“您不能将应用程序角色放入数据库角色”似乎是不正确的部分。 (应用程序)角色可以添加为另一个角色的成员:
EXEC sp_addrolemember 'db_owner', 'ApplicationRoleName';
(从2012年开始,此过程已被弃用,以支持新的ALTER ROLE .. ADD MEMBER
语法。)
要将整个数据库中的GRANT CONTROL
转换为角色,以下内容将:
USE [DatabaseName];
GRANT CONTROL ON DATABASE::[DatabaseName] TO [ApplicationRoleName];
USE
是在范围内发挥作用的必要条件;引用数据库时始终需要DATABASE::
范围限定符。
说了这么多,应用程序角色可能不是授予最广泛权限的好选择。它的密码以纯文本形式传递,除非注意加密连接本身,监视和审计可能会忽略它,并且在不再需要权限时很容易忘记恢复。最后一部分是额外的阴险,因为未转换的应用程序角色激活将在池化连接中持续存在,从而使管理模式中的连接“卡住”。替代方案包括使用新凭据为任意操作打开单独的连接,并使用EXECUTE AS
的存储过程获取无法有效进行GRANT
ed的权限。