Особенности использования USERELATIONSHIP при активных RLS-правилах
Если на платформе настроена безопасность на уровне строк (RLS), важно учитывать, что функция USERELATIONSHIP
не будет работать корректно для справочников, к которым применены правила RLS.
Рассмотрим простой пример.
Допустим, у нас есть модель данных с несколькими связями. Одна из связей активна (обозначена сплошной линией), другие – неактивны (обозначены пунктиром):
Для таблицы Products мы создадим RLS-роль OnlyFanta, которая будет позволять доступ только к данным о товарах с названием Fanta, и назначим эту роль пользователю Иванов:
Теперь мы создадим таблицу и добавим в нее столбец Название_Товара из таблицы Products и меру, которая имеет следующий код:
Продажи по промо-товарам = CALCULATE(
SUM('SalesFact'[salesamount]),
USERELATIONSHIP(
'SalesFact'[ID_Товара_Промо], Products[ID]
)
)
где
SUM('SalesFact'[salesamount])
– суммирует значения в столбцеsalesamount
таблицыSalesFact
.USERELATIONSHIP('SalesFact'[ID_Товара_Промо], Products[ID])
– указывает, что для вычисления суммы должен использоваться альтернативный путь связи между таблицами. Вместо стандартного соединения должна использоваться связь между полемID_Товара_Промо
в таблицеSalesFact
и полемID
в таблицеProducts
.
Таким образом, эта мера позволяет агрегировать данные о продажах промо-товаров, используя отношение между таблицами, которое является неактивным по умолчанию в модели данных.
В таблице на картинке выше представлен результат вычислений для пользователей, на которых не распространяется созданная RLS-роль. Однако пользователь Иванов, на которого распространяется RLS-роль, увидит следующее:
Это происходит, потому что Visiology проверяет наличие ограничений, и если таковые присутствуют при активном соединении, выводит сообщение об ошибке. Такое поведение соответствует политике безопасности, поскольку пользовательские DAX-формулы не должны приводить к утечке данных вне разрешенных прав доступа.
На текущий момент обойти это ограничение невозможно.
Однако существует также сценарий, при котором USERELATIONSHIP
и RLS могут взаимодействовать без возникновения ошибки.
Для демонстрации такого сценария мы деактивируем все связи между таблицами в нашем наборе данных, нажав на активную связь (сплошная линия) и выбрав Деактивировать в появившемся меню:
В результате мы получили модель данных, в которой все связи между таблицами Products и SalesFact являются неактивными.
Теперь, если пользователь Иванов, которому назначена роль RLS, посмотрит на таблицу, он увидит следующий результат:
Почему в данном случае не произошла ошибка? Дело в том, что RLS применяется только по активной связи. В нашей модели данных активная связь отсутствует, поэтому нет конфликта RLS – правила безопасности не накладываются на таблицу фактов напрямую. Фильтрация работает только на уровне справочника, который, в свою очередь, косвенно влияет на таблицу фактов. На саму таблицу фактов RLS-фильтрация не применяется, что и объясняет полученный результат.
Смотрите также
USERELATIONSHIP
Поддерживаемые функции DAX
Математические операторы
Нужна дополнительная помощь?