Как я могу получить chat_id только что отправленного или полученного сообщения?

В этом ответе говорится:

Существует идентификатор разговора, который одинаков на обеих конечных точках.

И есть talk_handle, который должен быть разным на каждой конечной точке.

Поэтому я подумал, что для устранения неполадок было бы полезно записать идентификатор разговора в таблицу аудита на каждой конечной точке разговора. Таким образом, я мог легко отслеживать информацию аудита на каждой конечной точке для данного диалога.

Проблема в том, откуда взять id_беседы. Первоначально я думал, что смогу найти его в sys.conversation_endpoints по дескриптору разговора только что отправленного или полученного сообщения. Однако пользователи базы данных, отправляющие и получающие сообщения, не имеют разрешений на просмотр метаданных в sys.conversation_endpoints.

Я мог бы обойти это, сделав пользователей, отправляющих и получающих сообщения, владельцами базы данных, но я бы предпочел этого не делать из соображений безопасности. Каковы минимальные разрешения, необходимые им для просмотра записей в sys.conversation_endpoints? В качестве альтернативы, как еще я мог прочитать talk_id сообщения, которое только что было отправлено или получено (из кода, выполняющего отправку или получение, который не имеет разрешений dbo или sysadmin)?

Изменить. Я прочитал в электронной документации статью о видимости метаданных. Конфигурация, в которой указано

видимость метаданных ограничена защищаемыми объектами, которыми пользователь владеет или на которые ему предоставлены определенные разрешения.

Для представлений каталога, таких как sys.tables или sys.procedures, достаточно очевидно, какие защищаемые объекты должны быть разрешены пользователю. Но какие защищаемые объекты перечислены в sys.conversation_endpoints: диалоги, конечные точки диалогов? И как вы даете им права? У пользователя уже есть разрешение начать диалог или завершить разговор, поэтому я подумал, что у него уже есть адекватное разрешение на разговор.


person Simon Tewsi    schedule 30.10.2013    source источник


Ответы (1)


Лучшее место, чтобы получить это от 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/SEND/END в этой службе:

Чтобы начать диалог, текущий пользователь должен иметь разрешение RECEIVE в очереди для службы, указанной в предложении FROM команды, и разрешение REFERENCES для указанного контракта
Чтобы отправить сообщение, < strong>текущий пользователь должен иметь разрешение на получение в очереди каждой службы, отправляющей сообщение.

MSND на самом деле ошибается в отношении разрешений END CONVERSATION, когда говорит: «Чтобы завершить активный разговор, текущий пользователь должен быть владельцем разговора, членом фиксированной роли сервера sysadmin или членом фиксированной роли базы данных db_owner». . Требуемое разрешение такое же, как и для SEND (это можно легко проверить).

Можно легко утверждать, что если вы можете манипулировать защищаемым объектом (а SEND, END явно манипулируют диалогами), то вы должны иметь возможность видеть метаданные защищаемого объекта, которыми манипулируют.

person Remus Rusanu    schedule 31.10.2013
comment
Большое спасибо за это, Ремус. Я дошел до того, что копался в sys.conversation_endpoints и просматривал sys.syssingleobjrefs через DAC. Мне показалось, что независимо от того, что has_access тестировал на принимающей стороне, была очередь отправки на дальнем конце. Поскольку я не мог предоставить разрешения очереди на дальнем конце, я сдался. Однако ваш пост в блоге о подписании хранимой процедуры активации выглядит многообещающе. - person Simon Tewsi; 01.11.2013
comment
Возможно, ошибка, которую предполагает Ремус, может существовать, была исправлена ​​в последних версиях SQL Server. Текущая система, над которой я работаю, соединяет экземпляр SQL Server 2012 Express с экземпляром SQL Server 2005 Standard. В конце SQL 2005 хранимая процедура активации не может видеть метаданные в sys.conversation_endpoints. Однако в конце SQL 2012 хранимая процедура активации может видеть метаданные. Хотя я мог сделать ошибку с разрешениями на любом конце, результаты для SQL 2012 обнадеживают. Не пробовал с SQL 2008 или 2008 R2. - person Simon Tewsi; 01.11.2013