сервис-брокер Сервер-участник sa не может получить доступ к базе данных в текущем контексте безопасности

Я работаю с SQL Server 2012 Express.

Я использую Service Broker для асинхронного запуска хранимой процедуры.

Процедура активации должна получить доступ к другой базе данных для выполнения другой хранимой процедуры. Это код:

CREATE PROCEDURE [dbo].[GetNewCodes]
    @gintNewCodes bigint,   
    @presNewCodes tinyint,
    @levelNewCodes bigint,
    @quantityNewCodes smallint
AS

    -- Get new codes from INCIC database.
    DECLARE @return_value int,
            @xmlGenerated xml,
            @xmlString NVARCHAR(MAX)

    SET NOCOUNT ON;

        -- Set that this stored procedure is running
        update dbo.RunningSPs with (serializable) set conf_value = 1
        where sp_name = N'GetNewCodes'

        if @@rowcount = 0
        begin
            insert dbo.RunningSPs(sp_name, conf_value) values (N'GetNewCodes', 1)
        end

    EXEC    @return_value = [INCIC].[dbo].[ReadCodeBuffer]
            @gint = @gintNewCodes,
            @pres = @presNewCodes,
            @level = @levelNewCodes,
            @quantity = @quantityNewCodes,
            @xmlGenerated = @xmlGenerated OUTPUT

    SET @xmlString = cast(@xmlGenerated as nvarchar(max))

    -- Process these new codes on TRZ.
    EXEC dbo.ProcessCodes @XmlString = @xmlString

    -- Update that we are not running this procedure any more.
    update dbo.RunningSPs with (serializable) set conf_value = 0
    where sp_name = N'GetNewCodes'

    if @@rowcount = 0
    begin
        insert dbo.RunningSPs(sp_name, conf_value) values (N'GetNewCodes', 0)
    end

Проблема здесь: [INCIC].[dbo].[ReadCodeBuffer], и сообщение об ошибке:

Ошибка: 50000
Неисправимая ошибка в процедуре GetNewCodes: 916: Субъект сервера "sa" не может получить доступ к базе данных "INCIC" в текущем контексте безопасности.

Я следовал этому учебнику для реализации службы, очереди и хранимой процедуры активации. .

Как я могу решить эту проблему?


person VansFannel    schedule 11.04.2014    source источник


Ответы (2)


Прочитайте Вызов процедуры в другой базе данных из активированная процедура.

Проблема заключается в том, что активированные процедуры выполняются в контексте ВЫПОЛНЯТЬ КАК ПОЛЬЗОВАТЕЛЬ и, таким образом, подлежат ограничениям олицетворения базы данных (они изолированы в базе данных). Все это объясняется в разделе Расширение олицетворения базы данных с помощью EXECUTE AS.

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

person Remus Rusanu    schedule 12.04.2014

Ответ Ремуса Русану явно окончательный и правильный. (Любой, кто имеет дело с брокерскими услугами, знает его опыт и бесценный блог.)

Я просто хотел задокументировать свой опыт, так как Google направит на этот вопрос при поиске «Субъект сервера «sa» не может получить доступ к базе данных...»

В моем случае я вызывал другую базу данных из активированной процедуры, но напрямую вызывал оператор sql, а не хранимую процедуру.

Изначально кросс-базовый вызов нормально работал без подписанного сертификата и использования олицетворения. Затем, после небольшого изменения синтаксиса, он начал возвращать вышеуказанное сообщение об ошибке.

Вот что работало без необходимости подписанного сертификата:

IF  EXISTS (SELECT name FROM sys.databases WHERE name = N'MyOtherDb')

и вот что спровоцировало исключение безопасности:

IF DB_ID(N'MyOtherDb') IS NOT NULL
person mdisibio    schedule 05.05.2016