Можно ли вызвать EXECUTE AS OWNER позже в объекте?

Рассмотрим этот код:

ALTER TRIGGER [dbo].[AfterInsertUpdateTenant_Korisnici] 
ON [dbo].[Korisnici]
WITH EXECUTE AS OWNER
FOR INSERT
AS
    DECLARE @TenantId INT = dbo.GetCurrentTenantId();

    EXECUTE AS LOGIN = 'sa';

    UPDATE Korisnici
    SET TenantId = @TenantId
    FROM Inserted i
    WHERE Korisnici.Id = i.Id;

    REVERT;

На каждом столе есть политика безопасности, которая не позволяет изменять TenantId столбец в таблице, отличный от того, который связан с пользователем базы данных, но политика разрешит его для пользователя "sa".

Проблема в TenantIdМне нужно получить TenantId с вызывающим принципалом, потому что TenantId привязан к пользователю базы данных. Я знаю одно решение: без with execute в триггере и вызывая процедуру, которая имеет with execute после того как я получу TenantId и передать его в процедуру, но тогда мне придется скопировать таблицу Inserted во временную таблицу, чтобы я мог получить к ней доступ в процедуре.

Я хотел бы лучше решение, где я могу позвонить execute as owner позже в объекте, после того как я получу TenantId, Логически это верно, но вопрос в том, они реализовали это? execute as login = 'sa' то, что вы видите в коде, не является хорошим решением, поскольку требует, чтобы текущий логин мог выдавать себя за sa авторизоваться.

Смысл этого триггера состоит в том, чтобы позволить пользователю не указывать TenantId на вкладыше. Я не должен даже упоминать TenantId в приложении все только на SQL Server.

Другое решение было бы, если бы создатель объекта мог написать некоторую информацию об объекте, которую я мог бы прочитать в политике безопасности и на основе этой информации позволить пользователю обновить TenantId, Это могут быть даже разрешения на объект, но вопрос в том, как я могу прочитать, какой объект вызвал вызов политики безопасности?

1 ответ

Решение

Я нашел решение, в котором триггер вызывает процедуру, которая в схеме запрещена для пользователя. Триггер не имеет "with execute" и может получить TenantId и переслать эту информацию в процедуру. В процедуре я имею "с исполнителем как владелец" и могу изменять записи, касающиеся любого Арендатора. Кроме того, я копирую необходимые столбцы таблицы Inserted в временную таблицу, чтобы процедура могла это увидеть, но я не вижу способа обойти это.

Еще лучшее решение:

alter trigger [dbo].[AfterInsertUpdateTenant_Korisnici]
on [dbo].[Korisnici]
with execute as owner
for insert 
as 
execute as user = original_login();
declare @TenantId int = dbo.GetCurrentTenantId();
revert;

update dbo.Korisnici
set TenantId = @TenantId
from Inserted i
where dbo.Korisnici.Id = i.Id;
Другие вопросы по тегам