简体   繁体   English

以后可以在对象中调用EXECUTE AS OWNER吗?

[英]Is it possible to call EXECUTE AS OWNER later in object?

Consider this code: 考虑以下代码:

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;

On every table, there is a security policy that doesn't allow change of the TenantId column on the table other than the one that is bound to the database user, but the policy will allow it for the "sa" user. 在每个表上,都有一个安全策略,除与数据库用户绑定的安全策略外,不允许更改表上的TenantId列,但该策略允许“ sa”用户使用。

Problem is TenantId , I need to get the TenantId with the calling principal because TenantId is bound to the database user. 问题是TenantId ,我需要获取带有调用主体的TenantId ,因为TenantId绑定到数据库用户。 I know one solution: without with execute in a trigger and calling a procedure that has with execute after I get TenantId and pass it into a procedure, but then I'd have to copy table Inserted into temp table so that I can access it in the procedure. 我知道一个解决方案:在获取TenantId并将其传递给过程之后,无需在触发器中with execute并调用with execute的过程,但是随后我必须将表插入到临时表中,以便可以在步骤。

I would like better a solution where I can call execute as owner later in object, after I get the TenantId . 我想要一个更好的解决方案,在我得到TenantId之后,可以稍后在对象中execute as owner Logically it's valid, but the question is; 从逻辑上讲是有效的,但问题是; have they implemented it? 他们实施了吗? execute as login = 'sa' that you can see in the code is not a good solution because it requires that current login is able to impersonate the sa login. 在代码中看到的execute as login = 'sa'不是一个好的解决方案,因为它要求当前的登录名能够模拟sa登录名。

Point of this trigger is to allow a user not to specify TenantId on an insert. 此触发器的目的是允许用户不要在插入TenantId上指定TenantId I don't have to even mention TenantId in the application, everything is only on the SQL Server. 我什至TenantId在应用程序中提及TenantId ,所有内容仅在SQL Server上。

Another solution would be if the creator of an object could write some info on an object that I could read in security policy and based on that info allow the user to update the TenantId . 另一个解决方案是,对象的创建者是否可以在安全策略中读取我可以读取的对象信息,并基于该信息允许用户更新TenantId It may even be permissions on the object but the question is how can I read which object caused the call of the security policy? 它甚至可能是对对象的权限,但问题是如何读取导致安全策略调用的对象?

I've figured out a solution where trigger calls the procedure that is in the schema forbidden to a user. 我想出了一个解决方案,其中触发器调用了用户禁止的模式中的过程。 The trigger has no "with execute" and can get TenantId and forward that info to the procedure. 触发器没有“ with execute”,可以获取TenantId并将该信息转发给过程。 In the procedure, I have "with execute as owner" and is able to change records regarding any Tenant. 在该过程中,我具有“以所有者身份执行”,并且能够更改有关任何租户的记录。 Also, I am copying needed columns of the Inserted table into the temp table so that the procedure can see it, I don't see a way around that. 另外,我将Inserted表的所需列复制到temp表中,以便过程可以看到它,但看不到解决方法。

Even better solution: 更好的解决方案:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM