首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 10g 列值遮罩:利用 VPD 實現敏感欄位動態脫敏

     編輯:Oracle 資料庫基礎

業務痛點:權限控制到「行」不夠,還要控制到「欄」

傳統 VPD (Virtual Private Database / FGAC) 透過策略函數動態拼接 WHERE 子句,實現**行級**安全。但業務常需:**全體可見某表所有行,但薪資、獎金等敏感欄位僅授權角色可見,其他人看見 NULL**。Oracle 10g 引入 **Column Masking(列值遮罩)** 完美解決此需求。

核心機制:兩個關鍵參數組合

  1. SEC_RELEVANT_COLS:指定「安全相關欄位」(如 salary, commission_pct)。
  2. SEC_RELEVANT_COLS_OPT => DBMS_RLS.ALL_ROWS:啟用「返回所有行,敏感欄位遮罩為 NULL」模式。

若無 ALL_ROWS,查詢包含敏感欄位時會直接套用策略函數過濾行;有 ALL_ROWS 時,行全返,敏感欄位轉 NULL。

完整實戰範例

1. 策略函數:返回部門過濾條件

CREATE OR REPLACE FUNCTION rls_dept (
  obj_owner IN VARCHAR2,
  obj_name  IN VARCHAR2
) RETURN VARCHAR2 AS
  predicate VARCHAR2(200);
BEGIN
  predicate := 'department_id = 60';  -- 實務中可根據 SYS_CONTEXT 判斷用戶部門
  RETURN predicate;
END rls_dept;
/
-- 測試授權
GRANT EXECUTE ON rls_dept TO PUBLIC;

2. 綁定策略並啟用列值遮罩

BEGIN
  DBMS_RLS.ADD_POLICY(
    object_schema      => 'HR',
    object_name        => 'EMPLOYEES',
    policy_name        => 'restrict_dept_policy',
    function_schema    => 'HR',
    policy_function    => 'rls_dept',
    sec_relevant_cols  => 'salary,commission_pct',      -- 敏感欄位清單
    sec_relevant_cols_opt => DBMS_RLS.ALL_ROWS          -- 關鍵:啟用遮罩模式
  );
END;
/
-- 移除策略:DBMS_RLS.DROP_POLICY('HR','EMPLOYEES','restrict_dept_policy');

行為驗證

查詢語句執行結果說明
SELECT * FROM employees;返回所有行,salary/commission_pct 顯示 NULL未查詢敏感欄位,策略不觸發,但遮罩生效
SELECT first_name, salary FROM employees;返回所有行,salary 顯示 NULL查詢含敏感欄位,遮罩生效
SELECT first_name FROM employees WHERE department_id=60;僅返回部門 60 的行,salary 正常顯示滿足策略函數條件,視為授權用戶,敏感欄位解除遮罩

關鍵特性與限制

  • 客戶端無關:SQL*Plus、JDBC、.NET、ODP.NET 等所有連線方式均生效。
  • 僅支援 SELECT:DML 不受 VPD 遮罩影響(但可用觸發器/審計管控)。
  • 索引影響:遮罩不改變儲存值,索引仍對明文有效,查詢計畫不變。
  • 11g+ 增強:支援 DBMS_RLS.ADD_POLICY(..., policy_type => DBMS_RLS.CONTEXT_SENSITIVE) 緩存策略謂詞,減少函數呼叫開銷。

結語

列值遮罩以「最小權限原則」在資料庫層原生實現欄位級脫敏,零改造應用程式,零效能損耗(除策略函數計算),是合規、多租戶、外包開發場景的首選方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved