行级安全更新块谓词不起作用

Row Level Security update block predicate not working

考虑以下 tables:

客户端 table 列:

带有列的工单 table:

考虑使用以下更新谓词函数,它应该允许客户只更新他们自己的票:

CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_guid AS sysname) RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) =
    (SELECT ticket_client_guid
     FROM dbo.ticket
     WHERE ticket_guid = @ticket_guid)

然后我们有应用谓词 fn 的安全策略:

CREATE SECURITY POLICY [Security].[ticket_security] 
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_guid]) ON [dbo].[ticket] BEFORE UPDATE 
WITH (STATE = ON, SCHEMABINDING = ON)

问题:客户能够将属于其他人的工单重新分配(更改工单_client_guid)给他。 注意:如果更新了其他一些票证字段,安全性工作得很好并且符合预期。

问题:这种行为是预期的吗?是否有解决此问题的方法?

注意:我尝试使用更新语句之前和之后的语句,并且在尝试更新谓词 fn (ticket_client_guid) 中引用的列时,其中 none 按预期运行。

来自https://docs.microsoft.com/en-us/sql/t-sql/statements/create-security-policy-transact-sql?view=sql-server-ver15#permissions

块谓词在执行相应的 DML 操作后计算。因此,READ UNCOMMITTED 查询可以看到将回滚的临时值。

如果有人将 ticket_client_guid 更新为他们的 ID,如果您在 table 中查询它,谓词将使用该新值进行安全检查。

我认为您需要使用传入函数的值,因此您可能必须使用其他 guid,以便它可以与原始值一起传递。也许

CREATE FUNCTION [Security].[fn_ticket_edit](@ticket_client_guid AS uniqueidentifier) 
RETURNS TABLE WITH SCHEMABINDING AS RETURN
SELECT 1 AS fn_securitypredicate_result
WHERE CAST(SESSION_CONTEXT(N'client_guid') AS uniqueidentifier) = @ticket_client_guid

CREATE SECURITY POLICY [Security].[ticket_security] 
ADD BLOCK PREDICATE [Security].[fn_ticket_edit]([ticket_client_guid]) ON [dbo].[ticket] BEFORE UPDATE 
WITH (STATE = ON, SCHEMABINDING = ON)