В каком порядке PostgreSQL проверяет права доступа к объектам?

16

Учитывая роль базы данных, user1функцию, something()определенную как хранимая процедура, и представление, созданное следующим образом:

CREATE VIEW view1 AS select * from something()

И, учитывая это разрешения:

REVOKE ALL ON FUNCTION something FROM user1
REVOKE SELECT ON view1 FROM user1

Когда я бегу SELECT * FROM view1, я получаю ошибку permission denied for function something().

Мой вопрос: если я отменяю права на выборку для представления, почему вызывается функция? Я ожидал получить что-то вроде:

permission denied for relation view1

Спасибо!

santios
источник
2
AFAIK нет определенного порядка, в котором проверяются разрешения.
Крейг Рингер
@CraigRinger Спасибо! Я предполагаю, что это ожидаемое поведение тогда. Поскольку я представляю представление в API, я пытался избежать раскрытия деталей реализации представления (учитывая сообщение об ошибке с жалобами на разрешения функции вместо представления).
santios
1
Я подозреваю, что разрешения оцениваются во многом так же, как планы запросов моды (например, снизу вверх), и, как таковой, сначала оценивается самый низкий объект, который в вашем случае является something()функцией. Быстрый тест состоял бы в том, чтобы изменить запрос таким образом, чтобы вы получили другой план объяснения, соответствующим образом скорректировав разрешения, а затем посмотрите, не возникла ли ошибка разрешения в something()функции или следует ли, как новый план выполнения переоценивается.
Джон Айсбренер
Если вы предоставляете разрешения для функции и отзываете их в представлении, в нем не должно быть упоминаний о базовой функции
amenadiel

Ответы:

3

Проблема в этом случае не совсем в порядке разрешения, а в порядке выполнения.

В резюме, для PostgreSQL:

1. Представления, которые обрабатывают таблицы, переопределят разрешение таблиц.

2- Функции доступа к представлениям должны будут оценить все функции перед проверкой - поэтому функции должны выполняться перед обработкой представления, даже если представление не имеет разрешений выбора ...

Как мы можем доказать это?

В postgresql представления могут дать вам разрешения на выбор в таблице, даже если у пользователя нет этих разрешений.

Например:

create view view2 as select * from table1;
revoke all on table1 from user1;
grant select on view2 to user1; 

Войдите как пользователь 1:

select * from table1 (permission denied) 
select * from view2 (sucess - the query executes)

В этом случае пользователь сможет выбрать view2, даже не имея разрешения на выбор таблицы.

Но что если мы сделаем то же самое с функцией ? Поведение НЕ одинаковы. Давайте создадим функцию, которая ждет 5 секунд, прежде чем вернуть 1 (поэтому мы можем отлаживать, если postgresql запускает функцию каждый раз, когда мы вызываем представление)

CREATE OR REPLACE FUNCTION something() RETURNS integer
AS 'select 1 from pg_sleep(5);'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT; --this function will delay 5 seconds

create view view1 as select * from something();
revoke all on function something() from user1;
grant select on view1 to user1; 

Войдите как пользователь 1:

select * from something(); (permission denied for something) 
select * from view1 (permission denied for something )

Разрешение на выбор в представлении не отменяет разрешение функции, и даже в худшем случае, если мы отзовем разрешения у view1, сообщение все равно показывает, что postgresql остановил наш запрос из-за функции, независимо от того, какое разрешение у представления. (это именно то, что происходит в вопросе)

Но действительно ли функция проверяется первой? Если мы дадим «все» разрешения для функции, но отзовем разрешение на просмотр ...

grant all on function something to user1; 
revoke all on view1 from user1; 
select * from view1;
Delayed 5 seconds... (the function executed!) 
Permission denied for select on view1

Как вы видите, postgresql WAITED 5 SECONDS перед тем, как сказать, что у нас нет разрешения на вывод представления , показывает, что выполняется функция " thing () ". Поэтому функция возврата данных должна существовать до проверки представления.

Итак, теперь с этими тестами мы теперь знаем, что PostgreSQL нужно было сначала оценить все функции, прежде чем продолжить наш запрос, точно так же, как запрос все еще не существует, пока все функции не будут полностью завершены, поэтому представление не может быть решено для postgresql для знать, есть ли у нас разрешение на его выбор.

Я думаю, что это ответ на ваш вопрос в терминах «порядка разрешений», но почему postgresql должен оценить все функции, прежде чем продолжить, вот другой вопрос ...

777Anon
источник