Postgresql

PostgreSQL 以什麼順序檢查對象權限?

  • April 30, 2018

給定一個數據庫角色,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

謝謝!

這種情況下的問題不完全是權限順序,而是執行順序。

在簡歷中,對於 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。

但是如果我們對一個函式做同樣的事情呢?行為一樣。讓我們創建一個在返回 1 之前等待 5 秒的函式(這樣我們就可以調試 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 一樣,表明“something()”函式已執行。所以函式數據返回必須存在於視圖的檢查之前。

所以現在通過這個測試,我們現在知道 PostgreSQL 在繼續我們的查詢之前需要首先評估所有函式,就像查詢仍然不存在,直到所有涉及的函式都完全完成,所以不能為 postgresql 解決視圖知道我們是否有權選擇它。

我認為這在“權限順序”方面回答了您的問題,但是為什麼 postgresql 需要在繼續之前評估所有功能,那是另一個問題……

引用自:https://dba.stackexchange.com/questions/172783