0

考虑这段代码:

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并将其传递给过程之后,我必须将表插入到临时表中,以便我可以在过程中访问它。

我想要一个更好的解决方案execute as owner,在我得到TenantId. 从逻辑上讲它是有效的,但问题是;他们实施了吗?execute as login = 'sa'您可以在代码中看到这不是一个好的解决方案,因为它要求当前登录能够模拟sa登录。

此触发器的要点是允许用户不指定TenantId插入。我什至不必TenantId在应用程序中提及,一切都只在 SQL Server 上。

另一种解决方案是,如果对象的创建者可以在对象上写入一些我可以在安全策略中读取的信息,并基于该信息允许用户更新TenantId. 它甚至可能是对象的权限,但问题是我如何才能读取导致调用安全策略的对象?

4

1 回答 1

0

我想出了一个解决方案,其中触发器调用模式中禁止用户使用的过程。触发器没有“执行”,可以获取 TenantId 并将该信息转发给过程。在此过程中,我“以所有者身份执行”并且能够更改有关任何租户的记录。另外,我正在将 Inserted 表的所需列复制到 temp 表中,以便该过程可以看到它,但我看不到解决方法。

更好的解决方案:

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;
于 2018-06-22T22:55:57.920 回答