Consider having the following tables:
Client table with columns:
- client_guid(uniqueidentifier - primary key)
- client_description
Ticket table with columns:
- ticket_guid(uniqueidentifier - primary key)
- ticket_client_guid(uniqueidentifier - foreign key to client table)
- ticket_description.
Consider having the following update predicate function which is supposed to allow clients to update only their own tickets:
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)
Then we have the security policy applying the predicate 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)
Problem: Client being able to reassign a ticket (change ticket_client_guid) to him which belongs to somebody else. Note: The security works perfectly fine and as expected if some of the other ticket fields is updated.
Question: Is this behavior expected and is there a workaround for this problem ?
Note: I tried playing with both before and after update statements and none of them worked out as expected when trying to update the column referenced in the predicate fn (ticket_client_guid).