PostgreSQL 以什麼順序檢查對象權限?
給定一個數據庫角色,
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 需要在繼續之前評估所有功能,那是另一個問題……