Я использую 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, а не для хранилища данных и их пользователей. Я контролирую, какие операторы передаются в базовые запросы - и представления / функции никогда не отображаются «напрямую».