许多嵌套对象的 SA 权限问题

JNK*_*JNK 5 security sql-server permissions sql-server-2008-r2 service-broker

我有一个相对复杂的经纪人应用程序。

今天,在我进行了一些更改后,我开始收到错误消息:

服务器主体“sa”无法在当前安全上下文下访问数据库“XYZ”。

到错误点为止的整个场景是:

(在数据库ABC 中

  • 代理消息被提交到队列中
  • 队列阅读器拿起它
  • 队列读取器更新表以指示工作正在开始
  • 该表有一个更新触发器。触发
    • 检查数据库XYZ 中的表以确保此字段的插入值有效
    • 该表通过同义词访问

我认为触发器中的检查是导致问题的原因。

如果我手动运行更新,它工作正常。我也曾经EXECUTE AS手动运行更新,因为sa它工作正常。

其他相关事实:

  • sa是数据库ABC和数据库XYZ的所有者
  • sa 帐户没有什么有趣的事情 - 它也是两个数据库中的 db_owner 角色

是否有某种奇怪的作用域发生,因为所有这些都在代理的上下文中运行?

更新

更多信息:

  • 数据库所有权链接在服务器级别上,但不在数据库中。我打开它并没有什么区别。
  • 使用三部分名称而不是同义词没有区别
  • 探查器跟踪显示这些语句作为 SA 而不是另一个登录运行
  • 将两个数据库 TRUSTWORTHY 设置为 ON 没有任何区别
  • 如果我手动运行队列激活过程,它会正确处理(在我的凭据下)。

Jān*_*nis 1

可以告诉你我在像你这样的情况下想出的解决方案(它非常复杂,但仍然喜欢它):

我有带有 Service Broker 的数据库DB1和DB2,其中数据也必须更新(我在 DB2 中也有触发器)。

我正在使用证书在每个数据库中创建服务器登录名+用户。我正在签署授予权利的程序和触发器。您可以在这里阅读您需要的所有内容。

-- Master DB:
CREATE CERTIFICATE MyCertificate
WITH SUBJECT = 'Example'
Go
BACKUP CERTIFICATE MyCertificate TO FILE = 'c:\Cert.cer' 
    WITH PRIVATE KEY ( 
    FILE = 'c:\CertKey.key', 
    ENCRYPTION BY PASSWORD = 'pwd');
Go
Create Login CertLogin From Certificate MyCertificate

-- DB1:
CREATE CERTIFICATE MyCertificate
FROM FILE = N'c:\Cert.cer'
WITH PRIVATE KEY
    (
        FILE = N'c:\CertKey.key',
        DECRYPTION BY PASSWORD = N'pwd'
    ); 

Create User CertUser From Login CertLogin;

-- DB2:
CREATE CERTIFICATE MyCertificate
FROM FILE = N'c:\Cert.cer'
WITH PRIVATE KEY
    (
        FILE = N'c:\CertKey.key',
        DECRYPTION BY PASSWORD = N'pwd'
    ); 
Go
CREATE USER [CertUser] FROM Login CertLogin;
Run Code Online (Sandbox Code Playgroud)

授予权限(在我的例子中,不需要选择/插入/更新/删除权限,因为 DB2 中的所有表和过程都在同一模式中。因此 DB2 中的所有权链接):

-- DB1:
Grant Exec On dbo.usp_MyProc_DB1 To SomeUser -- User that calls procedure
ADD SIGNATURE TO dbo.usp_MyProc_DB1 BY CERTIFICATE MyCertificate;
-- DB2:
ADD COUNTER SIGNATURE TO dbo.usp_MyProc_DB2 BY CERTIFICATE MyCertificate; 
ADD COUNTER SIGNATURE TO tr_MyTrigger_DB2 BY CERTIFICATE MyCertificate;
Grant Exec On usp_CheckPatientDetailedRole To CertUser;
Run Code Online (Sandbox Code Playgroud)