SQL Server Row Level Security не работает на внешних ключах
У меня работает база данных SQL Azure. Там у меня есть 3 таблицы
- пользователей
- UserProject
- проектов
Нормальные отношения многие ко многим. Пользователь может иметь несколько проектов, а проект может иметь несколько пользователей. Строки связаны идентификаторами, и ForeignKey-Constraitns устанавливаются соответственно.
Я хочу включить безопасность на уровне строк для таблицы проектов. Вот что я сделал:
CREATE FUNCTION dbo.fn_predicate(@tenant varchar(25))
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN SELECT 1 AS fn_accessResult
WHERE SESSION_CONTEXT(N'Tenant') = @tenant ;
GO
Затем я создал политику:
CREATE SECURITY POLICY mandantPolicy
ADD FILTER PREDICATE dbo.fn_predicate(Tenant) ON dbo.Projects,
ADD BLOCK PREDICATE dbo.fn_predicate(Tenant) ON dbo.Projects
GO
Затем я включил политику, и она работает нормально. Это означает, что я могу видеть только проекты арендатора, для которого я установил SESSION_CONTEXT. А также вставка заблокирована соответственно..
Например:
-- Works as expected (new project inserted)
EXEC SP_SET_SESSION_CONTEXT @key=N'Tenant', @value='foo'
INSERT INTO Projects (Name, Tenant) VALUES ('Dummy', 'foo')
-- Works as expected (insert blocked)
EXEC SP_SET_SESSION_CONTEXT @key=N'Tenant', @value='bar'
INSERT INTO Projects (Name, Tenant) VALUES ('Dummy', 'foo')
Я ожидал бы, что эта защита на уровне строк также будет применена к таблице отношений UserProject. Например:
-- Insert a new project for tenant 'foo'
-- This results in a new project with id 1
EXEC SP_SET_SESSION_CONTEXT @key=N'Tenant', @value='foo'
INSERT INTO Projects (Name, Tenant) VALUES ('Dummy', 'foo')
-- Try to link the project from tenant foo with a user (id 5) but as tenant 'bar'
EXEC SP_SET_SESSION_CONTEXT @key=N'Tenant', @value='bar'
INSERT INTO UserProject (ProjectId, UserId) VALUES (1, 5)
По моему мнению, этот последний INSERT должен быть заблокирован, поскольку арендатор настроен на "bar", и поэтому проект, который ранее был добавлен как арендатор "foo", не должен быть виден пользователю "bar".
Я здесь пропускаю какие-либо настройки? Или это просто не поддерживается RLS?