Безопасность на уровне строк на основе функции IS_MEMBER - PullRequest
1 голос
/ 19 марта 2020

Цель

Я реализую безопасность на уровне строк (RLS) на Azure Синапс на основе аутентификации Active Directory (AD). Идея состоит в том, что клиенты, добавленные в security_group_A_access, имеют доступ ко всем строкам MY_TABLE со столбцом CATEGORY = 'A'. См. Код ниже.

Проблемы

  1. IS_MEMBER Функция вызывается один раз для каждой строки, в результате чего запрос SELECT DISTINCT CATEGORY FROM MY_TABLE выполняется более 3 минут вместо 1 секунды. Кажется, что это общая проблема .
  2. Даже при жестком кодировании условия fn_predicate с WHERE CATEGORY = 'A' (удаление IS_MEMBER invocation) запросы становятся медленнее. Таблицы RLS имеют до миллиарда строк и используются для отчетов Power BI, поэтому для них очень важно производительность / время отклика.

Вопросы

  1. Есть ли способ вызвать IS_MEMBER функцию не чаще, чем есть группы безопасности? Значит ли это как-то кешировать результат или сохранить его в глобальной переменной, et c.
  2. Является ли RLS общий подход для таблицы с миллиардами строк с критической производительностью? Или это обычная практика - создавать представление для каждой группы безопасности AD?

Код

CREATE SCHEMA [security]
GO

CREATE FUNCTION [security].[fn_predicate](@category_column as varchar(50))
RETURNS TABLE
WITH SCHEMABINDING
AS
  RETURN SELECT 1 AS fn_predicate
  WHERE IS_MEMBER(CONCAT('security_group_', @category_column, '_access')) = 1
GO

GRANT SELECT ON [security].[fn_predicate] TO security_group_A_access
GRANT SELECT ON [security].[fn_predicate] TO security_group_B_access
GO

CREATE SECURITY POLICY MY_TABLE_FILTER
ADD FILTER PREDICATE [security].[fn_predicate]([CATEGORY])
ON [dbo].[MY_TABLE]
WITH (STATE = ON)
GO

PS

Я могу перефразировать этот вопрос следующим образом: - Есть ли варианты лучше, чем 1-й?

Три возможных подхода:

  1. Создать представление для CATEGORY и ограничить каждую группу для отдельного просмотра.

    • Плюсы: На производительность MY_TABLE для отчетов PBI не влияет
    • Минусы: Количество просмотров. Предположим, у вас есть категории A, B, C, D, E. Чем вам нужно 5 просмотров. Что если есть пользователь, который состоит из групп A и C?
  2. Применить RLS поверх MY_TABLE.

    • Плюсы: Мой текущий подход. Прост в реализации, без дополнительных таблиц и представлений. Масштабируемый, в случае большего количества КАТЕГОРИЙ, будут добавлены группы или правила.
    • Минусы: См. Раздел «Проблемы». На производительность MY_TABLE практически не влияют и не приемлемы
  3. Гибридный подход. Создайте одиночный MY_TABLE_VIEW и примените RLS поверх представления.

    • Плюсы: все преимущества второго варианта плюс производительность MY_TABLE для отчетов PBI не влияют .
    • Минусы: еще нужно решить IS_MEMBER проблему с производительностью, см. 1-й пункт в разделе «Проблемы».
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...