1

这个答案说:

有一个conversation_id,在两个端点都相同。

还有conversation_handle,每个端点都必须不同。

因此,我认为将对话 ID 写入对话每个端点的审计表对于故障排除很有用。这样我就可以轻松地在给定对话的每个端点追踪审计信息。

问题是从哪里获取会话 ID。我原本以为我可以从 sys.conversation_endpoints 对照刚刚发送或接收的消息的 conversation_handle 进行查找。但是,发送和接收消息的数据库用户无权查看 sys.conversation_endpoints 中的元数据。

我可以通过让用户发送和接收消息数据库所有者来解决这个问题,但出于安全原因我不希望这样做。他们查看 sys.conversation_endpoints 中的记录所需的最低权限是多少?或者,我还能如何读取刚刚发送或接收的消息的 conversation_id(从进行发送或接收的代码中,没有 dbo 或 sysadmin 权限)?

编辑:我阅读了有关元数据可见性配置的在线图书文章,其中指出

元数据的可见性仅限于用户拥有或已被授予某些权限的安全对象

对于诸如 sys.tables 或 sys.procedures 之类的目录视图,用户需要被授予权限的安全对象是相当明显的。但是 sys.conversation_endpoints 中列出的安全对象是什么:对话、对话端点?以及如何授予他们权限?用户已经有权开始对话或结束对话,所以我认为它已经拥有足够的对话权限。

4

1 回答 1

2

获得它的最佳地点是从sys.conversation_endpoints.

每当您遇到应用程序需要当前用户未拥有的权限的问题时,最好的选择是利用代码签名。SQL Server 允许管理员使用证书检查和签署存储过程,并授予对签名的权限。这允许用户调用该过程并且该过程可以访问用户不能直接访问的信息。

有关示例,请参阅签署激活的程序

至于为什么您看不到自己的对话:恕我直言,这是一个错误。运行sp_helptext 'sys.conversation_endpoints'显示应用的权限过滤器:

 CREATE VIEW sys.conversation_endpoints AS
SELECT ce.conversation_handle,
    ...
    FROM sys.conversation_endpoints$ ce
LEFT JOIN sys.syssingleobjrefs f 
      ON f.depid = ce.service_id 
      AND f.class = 21 
      AND f.depsubid = 0 -- SRC_SVCTOQUEUE
WHERE has_access('CO', f.indepid) = 1

该视图显示了用户对对话所属的服务队列具有 CONTROL 访问权限的对话(需要一些专业知识syssingleobjrefs才能了解视图条件是什么,但要了解它转换为什么)。权限检查应该是针对RECEIVE权限的,因为那是在这个服务上 // 消息需要BEGIN DIALOG的权限SENDEND

要开始对话,当前用户必须对命令的 FROM 子句中指定的服务的队列具有 RECEIVE 权限,并且对指定的合同具有 REFERENCES 权限
要发送消息,当前用户必须对每个队列具有 RECEIVE 权限发送消息的服务。

MSND 在权限主题上实际上是错误的,END CONVERSATION它说“要结束活动对话,当前用户必须是对话的所有者、sysadmin 固定服务器角色的成员或 db_owner 固定数据库角色的成员”。所需的权限与 for 的权限相同SEND(这很容易测试)。

可以很容易地认为,如果您可以操纵安全对象(并且 SEND、END 显然是在操纵对话),那么人们应该能够看到被操纵的安全对象的元数据。

于 2013-10-31T15:46:45.560 回答