三個擁有 DBA 角色的用戶 TEST1/TEST2/TEST3,TEST1 建表授權 TEST2,TEST2 建視圖授權 TEST3,TEST3 查詢視圖卻報 ORA-01031: 權限不足。本文深度解析視圖權限的兩大核心規則:角色權限屏蔽、授權鏈路完整性 (WITH GRANT OPTION),並給出修正方案。
-- TEST1
CREATE TABLE t1 AS SELECT * FROM all_objects;
GRANT SELECT ON t1 TO test2; -- 缺少 WITH GRANT OPTION
-- TEST2
CREATE VIEW v_t1 AS SELECT * FROM test1.t1;
GRANT SELECT ON v_t1 TO test3;
-- TEST3 (擁有 DBA 角色)
SELECT * FROM test2.v_t1 WHERE rownum < 1;
-- ORA-01031: insufficient privileges
SELECT ANY TABLE 系統權限,**視圖內部引用的基表權限必須由定義者顯式擁有**,角色權限不生效。v_t1 授權 TEST3,實質上是**轉授** TEST1 表 t1 的查詢權限給 TEST3。WITH GRANT OPTION,否則鏈路中斷。GRANT SELECT ON t1 TO test2,**缺少 WITH GRANT OPTION**,導致 TEST2 無法轉授,TEST3 查詢失敗。-- TEST1 執行:補授 WITH GRANT OPTION
GRANT SELECT ON t1 TO test2 WITH GRANT OPTION;
執行後,TEST3 即可正常查詢 test2.v_t1。
視圖的 DML 權限轉授同樣要求基表授權時帶 WITH GRANT OPTION。若視圖不可更新 (含聚合、JOIN、DISTINCT 等),則無法授予 DML 權限。
測試發現:若 TEST2 **未顯式授權** 視圖給 TEST3,但 TEST3 擁有 SELECT ANY TABLE 或 DBA,則查詢**不報錯** (系統權限生效)。但一旦**顯式授權物件權限** (GRANT SELECT ON v_t1 TO test3),物件權限檢查優先,**且不與系統權限合併評估**,導致因缺少 WITH GRANT OPTION 而失敗。
→ 結論:顯式物件授權會「蓋過」系統權限,且嚴格檢查授權鏈路。生產環境建議:要么全靠系統權限 (不授物件權限),要么完整建立物件授權鏈路 (含 WITH GRANT OPTION),避免混用產生不可預期行為。