Oracle 原生權限模型僅支援物件級(表、視圖、函數等)的 SELECT/INSERT/UPDATE/DELETE/EXECUTE 控制,缺乏欄位級與列級權限機制。大型 MIS 系統中,同一張表不同角色往往只能存取特定資料子集(如:業務員僅看自己客戶、主管看部門全員、總經理看全公司),若在應用層硬編碼過濾邏輯,不僅開發維護成本高,更存在 SQL 注入繞過風險。
ALTER TABLE CUSTOMER ADD (
SGRANT_NUM NUMBER(20), -- 分片授權編號範圍
SUNIT_ID VARCHAR2(10) -- 所屬部門代碼
);CREATE OR REPLACE VIEW CUSTOMER_PV AS
SELECT * FROM CUSTOMER A
WHERE A.SUNIT_ID IS NULL
OR EXISTS (
SELECT 1 FROM CUSTOMER B
WHERE A.SUNIT_ID = B.SUNIT_ID
AND B.SGRANT_NUM >= TO_NUMBER(SUBSTR(USERENV('CLIENT_INFO'), 1, 10))
AND B.SGRANT_NUM <= TO_NUMBER(SUBSTR(USERENV('CLIENT_INFO'), 11, 10))
);-- 應用登入後執行
DBMS_APPLICATION_INFO.SET_CLIENT_INFO(
LPAD(grant_num_low, 10, '0') || LPAD(grant_num_high, 10, '0')
);當用戶查詢 CUSTOMER_PV 時,Oracle 自動將視圖定義中的 USERENV('CLIENT_INFO') 替換為當前會話的實際值,動態生成帶有篩選條件的執行計劃。對開發者透明,對用戶強制生效。
| 維度 | 優勢 | 劣勢 |
|---|---|---|
| 實作透明度 | 應用無感知,僅查詢視圖即可 | 主表結構變更需同步修改視圖定義 |
| 效能影響 | 伺服器端自動處理,巨量資料無明顯額外開銷 | 複雜關聯查詢可能影響執行計劃選擇 |
| 分片靈活度 | - | 僅支援縱向組織架構分片,難以支援橫向業務屬性分片 |
| 維護成本 | - | 組織調整需重新計算授權範圍並更新全員 CLIENT_INFO |
Oracle 8i+ 正式提供 DBMS_RLS 套件實現真正的行級安全策略,優於手工視圖方案:
CREATE OR REPLACE FUNCTION customer_security_predicate (
p_schema VARCHAR2, p_object VARCHAR2
) RETURN VARCHAR2 AS
v_grant_range VARCHAR2(20);
BEGIN
v_grant_range := SYS_CONTEXT('USERENV', 'CLIENT_INFO');
RETURN 'SGRANT_NUM BETWEEN ' || SUBSTR(v_grant_range, 1, 10) ||
' AND ' || SUBSTR(v_grant_range, 11, 10);
END;
/
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'APP_OWNER',
object_name => 'CUSTOMER',
policy_name => 'CUSTOMER_ORG_POLICY',
function_schema => 'SEC_ADMIN',
policy_function => 'CUSTOMER_SECURITY_PREDICATE',
statement_types => 'SELECT,INSERT,UPDATE,DELETE',
update_check => TRUE,
enable => TRUE
);
END;
/
CREATE CONTEXT + SYS_CONTEXT 更安全、可擴展DBMS_FGA 精細審計敏感資料存取資料分片非單純技術實作,而是安全模型與業務邏輯的深度融合。從早期的動態視圖方案演進至 VPD/OLS 原生框架,體現了 Oracle 安全架構從「事後過濾」向「事前阻擋」的根本轉變。現代企業級應用應直接採用 DBMS_RLS 構建零信任資料存取層,將安全邏輯下沉至資料庫核心,實現應用解耦與合規雙贏。