Функции определителя безопасности и представления для безопасности на уровне строк - PullRequest
1 голос
/ 05 мая 2020

Я использую RLS в схеме public базы данных Postgresql 10. Иногда у меня возникает обстоятельство, что политика RLS должна получить доступ к той же таблице, в которой она была создана (из-за базовой модели прав приложения), или мне нужно запросить таблицу для чистой производительности в контексте администратора, где правило RLS уже выполнено .

Итак, чтобы обойти бесконечную рекурсию (когда одна и та же таблица используется в политике) и причину производительности, я создал views и security definer functions с течением времени.

Итак, для Например, таблица public.verbatims теперь имеет представление, созданное владельцем таблицы:

CREATE VIEW private.verbatims_list AS (SELECT * FROM public.verbatims);

И функция:

CREATE OR REPLACE FUNCTION private.verbatims_list() RETURNS SETOF verbatims AS $$
  SELECT * FROM public.verbatims;
$$
STABLE
LANGUAGE SQL
SECURITY DEFINER;

Обе в настоящий момент выполняют свою работу.

Из того, что я почерпнул из документации Postgres по представлениям (https://www.postgresql.org/docs/current/sql-createview.html, раздел «Примечания») и по функциям (https://www.postgresql.org/docs/current/sql-alterfunction.html) - концепция та же. Просмотр / функция выполняется с разрешением owner. Так что это не должно иметь значения для моего варианта использования.

Однако я хочу провести рефакторинг, чтобы у нас были либо представления с правами владельца таблицы, либо функции определения безопасности.

Это справедливо для скажем, что оба одинаково функциональны для этого варианта использования или есть разница, о которой я должен знать? Использование функции кажется более «явным» в зависимости от варианта использования.


Обновление вопроса в отношении возможной оптимизации (из комментариев ниже) при использовании представления против функции.

Функции могут быть "встроенными" при определенных условиях:

Даже если это статья довольно старая - мои тесты показывают, что функция определения безопасности не может быть "встроенной" (что, я думаю, имеет смысл).

Я создал скрипт БД, чтобы продемонстрировать простой тест:

https://www.db-fiddle.com/f/qkWMitjcxHxX5wxmtoqfyB/4

При использовании функции verbatims_list_security() в простом запросе , Postgres использует просмотр функций, а не просмотр индекса. Мое предположение состоит в том, что использование индекса является «встраиваемым».

Также из комментариев: при использовании представления WITH (security barrier) (https://www.postgresql.org/docs/current/rules-privileges.html) необходимо для моего варианта использования. ?

Мое текущее мнение будет: вероятно, нет. Поскольку я использую RLS для обеспечения мультиарендности и прав acl в HTTP api, а не для хранилища данных и их пользователей. Я контролирую, какие операторы передаются в базовые запросы - и представления / функции никогда не отображаются «напрямую».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...