ROA*_*OAL 3 sql-server permissions sql-server-2012 users
我们有两个数据库,Adb和Bdb. 在Bdb,我们创建了一个观点,即引用另一种观点认为Adb,像这样:CREATE VIEW Bdb.dbo.Bview AS SELECT * FROM Adb.dbo.Aview。
我们有一个 SQL Authenticated Blogin,映射到Buser,Adb和Bdb,至少db_datareader在两者上都有角色。
以下不起作用:
USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Bdb.dbo.Bview;
SELECT * FROM Adb.dbo.Aview;
Run Code Online (Sandbox Code Playgroud)
两个选择都会引发以下错误:
Msg 916, Level 14, State 1, Line 4
The server principal "Buser" is not able to access the database "Adb" under the current security context.
Run Code Online (Sandbox Code Playgroud)
但是,这有效:
USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM Adb.dbo.Aview;
SELECT * FROM Bdb.dbo.Bview;
Run Code Online (Sandbox Code Playgroud)
我注意到当我第一次USE Bdb切换到 时Buser,我看不到任何其他数据库:
USE Bdb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- only master, tempdb and Bdb is shown
Run Code Online (Sandbox Code Playgroud)
但是,当我USE Adb第一次看到它们时,我看到了所有这些,即使是那些没有Buser并且无法通过它访问的:
USE Adb;
EXECUTE AS USER = 'Buser';
SELECT * FROM sys.databases; -- all DBs on the server are shown
Run Code Online (Sandbox Code Playgroud)
什么可能导致这个问题?我应该检查什么?
第一件事:不要让信任成为可能!!绝对没有理由打开这么大的安全漏洞。(注意:msdb已TRUSTWORTHY启用,这很好,因为它是 Microsoft 提供的数据库;用户创建的数据库永远不需要 TRUSTWORTHY启用)
现在,如果这在模拟用户而不是登录时有效,则是因为您的[Adb]数据库已被启用为TRUSTWORTHY ON,这将删除使用数据库级模拟时存在的默认隔离区。您可以通过执行以下操作来看到这一点:
SELECT db.is_trustworthy_on, *
FROM sys.databases db
WHERE db.[name] IN (N'Adb', N'Bdb');
Run Code Online (Sandbox Code Playgroud)
假设它是的情况下Adb为启用TRUSTWORTHY并Bdb没有,那么还是请不要启用TRUSTWORTHY的Bdb。这将是最好禁用 TRUSTWORTHY的Adb,并使用模块签名来实现:
ALTER DATABASE [Adb] SET TRUSTWORTHY OFF;
Run Code Online (Sandbox Code Playgroud)
有关通过模块签名进行跨数据库访问的示例,请参阅我的以下答案(在 DBA.SE 上):
访问基于另一个数据库中的表的视图,而无需在该另一个数据库中的帐户
有关为什么应该使用模块签名而不是 TRUSTWORTHY(甚至跨数据库所有权链接)的更多信息,请参阅我的以下帖子:
有关模块签名的更多信息,请参阅:
正如@Nic 在对该问题的评论中提到的,最好在测试时使用EXECUTE AS LOGIN而不是使用EXECUTE AS USER。登录位于服务器级别,并且可以访问已为该登录创建用户的数据库。这就像以该帐户登录 SQL Server 一样。
使用 EXECUTE AS 扩展数据库模拟的 Microsoft 文档页面中说明了差异的原因
了解模拟范围
...
但是,当使用 EXECUTE AS USER 语句模拟主体时,或使用 EXECUTE AS 子句模拟数据库范围的模块时,默认情况下模拟范围仅限于数据库。这意味着对数据库范围之外的对象的引用将返回错误。
此外,“Extending Database Impersonation by Using EXECUTE AS”MSDN 页面(上面链接)上有很多很好的信息,解释了身份验证器和这些规则背后的推理。
鉴于这两个数据库是供应商提供的(补充的信息,我提交了这个答案后),那么它可能是最好的,只是开关EXECUTE AS LOGIN和不使该数据库的任何变化(模块签名)。
| 归档时间: |
|
| 查看次数: |
11166 次 |
| 最近记录: |