使用者 APP_USER 需執行結構 SCHEMA_OWNER 下的預存程序 PROC_CALC,但不想授予 EXECUTE ANY PROCEDURE 這類高風險系統權限。
-- 1. 授予代理權限
ALTER USER schema_owner GRANT CONNECT THROUGH app_user;
-- 2. 應用端連線語法
CONNECT app_user[schema_owner]/app_pwd@DB
-- 或 JDBC
conn = DriverManager.getConnection(url, "app_user[schema_owner]", "app_pwd");
-- 3. 執行程序(視同 schema_owner 身分)
EXEC proc_calc(...);
優點:審計可見真實使用者、無需授予物件權限給 APP_USER、密碼不外露。
缺點:需資料庫 10g+、連線池需支援 Proxy 語法。
-- 1. 結構擁有者授權
GRANT EXECUTE ON proc_calc TO app_user;
-- 2. 建立同義詞(選擇性,簡化呼叫)
CREATE SYNONYM app_user.proc_calc FOR schema_owner.proc_calc;
-- 3. 呼叫
EXEC schema_owner.proc_calc(...); -- 或 EXEC proc_calc(...);
優點:標準、所有版本支援、權限粒度最細。
缺點:程序內若動態 SQL 參考基底表,仍需授予基底表權限(除非程序定義為 AUTHID DEFINER 預設行為)。
-- 在 schema_owner 下建立包裝程序
CREATE OR REPLACE PROCEDURE wrapper_proc_calc AUTHID DEFINER IS
BEGIN
proc_calc(...); -- 內部呼叫原程序
END;
/
GRANT EXECUTE ON wrapper_proc_calc TO app_user;
適用場景:原程序為 AUTHID CURRENT_USER (Invoker's Rights) 導致權限不足時,包裝為 Definer's Rights 繼承擁有者權限。
| 特性 | Proxy Auth | Grant Execute | Wrapper (Definer) |
|---|---|---|---|
| 審計身分 | 真實使用者 | 呼叫使用者 | 呼叫使用者 |
| 基底表權限 | 擁有者權限 | 需額外授予(Invoker) | 擁有者權限 |
| 密碼管理 | 僅 app_user 密碼 | app_user 密碼 | app_user 密碼 |
| 版本需求 | 10g+ | 所有 | 8i+ |
| 推薦指數 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
-- CDB$ROOT 下建立 Common User
CREATE USER c##app_user IDENTIFIED BY pwd CONTAINER=ALL;
GRANT CONNECT, CREATE SESSION TO c##app_user CONTAINER=ALL;
-- 在 PDB1 中授予 Proxy
ALTER SESSION SET CONTAINER = PDB1;
ALTER USER schema_owner GRANT CONNECT THROUGH c##app_user;
-- 連線指定 PDB
CONNECT c##app_user[schema_owner]/pwd@PDB1
首選 **Proxy Authentication**:安全、審計友善、零物件權限維護。次選 **Grant Execute + Synonym**:標準、相容性佳。僅在舊版本或特殊權限模型需求下使用 **Definer's Rights Wrapper**。嚴禁使用 EXECUTE ANY PROCEDURE 系統權限解決跨使用者呼叫問題。