VPD介紹
Oracle VPD(Virtual Private Database,虛拟私有資料庫)是一個Oracle資料庫的安全特性,它允許資料庫管理者定義和實施細粒度的資料通路控制政策。通過使用VPD,管理者可以定義行級别和列級别的安全政策,以控制使用者對資料庫中資料的通路。
Oracle VPD可以為不同的使用者提供不同的資料視圖,以控制對敏感資料的通路,具有如下優勢:
Ø 資料安全性:VPD可以控制不同使用者對資料庫中資料的通路權限,進而保證資料的安全性。隻有被授權的使用者可以通路資料,進而減少了因非授權使用者通路敏感資料而導緻的資料洩露或濫用的風險。
Ø 簡化開發:VPD可以讓開發人員在不改變應用程式代碼的情況下實作資料權限控制。這樣可以節省開發時間和開發成本,并且更加靈活地調整資料權限。
Ø 提高性能:VPD在資料庫查詢中應用了一些優化技術,例如謂詞下推,可以在保證資料安全性的前提下提高查詢性能。
Ø 簡化管理:VPD可以為管理者提供一種集中管理和控制資料庫通路權限的方式。管理者可以通過配置VPD規則來實作資料權限控制,而無需為每個使用者單獨配置通路權限。
Ø 降低風險:VPD可以控制使用者對敏感資料的通路權限,進而降低了資料洩露和濫用的風險。此外,VPD還可以記錄資料庫通路日志,幫助管理者跟蹤資料庫通路情況并發現潛在的安全威脅。
權限控制簡介
權限控制主要包括兩方面:功能控制和資料控制。APEX可以很友善的實作各種粒度的功能控制,從功能子產品、菜單、頁面到單個輸入框、按鈕等都可以通過配置的方式很友善的實作;本文将重點講述在APEX應用中如何結合Oracle資料庫的VPD特性友善靈活地實作資料層面的權限控制。
VPD政策配置
執行個體政策描述
作為執行個體,我們将實作一個這樣的政策:
【登入使用者能檢視他自己以及下屬(包括下屬的下屬…)所有銷售代表的訂單資料,不能檢視同一級其他員工的資料或上級的其它資料】
這裡涉及到兩個表:
Ø 員工表:定義了員工登入應用的資訊,以及員工的層級關系
OEHR_EMPLOYEES EMPLOYEE_ID – 員工ID EMAIL – 作為APEX應用的登入名 MANAGER_ID – 員工的上級經理 … … |
Ø 訂單表:定義了與員工相關聯的訂單
OEHR_ORDERS ORDER_ID – 訂單号 SALES_REP_ID – 銷售代表,對應員工表中的EMPLOYEE_ID … … |
要實作這樣一個政策,我們的目标其實就是 從OEHR_ORDERS表中找到所有屬于自己以及下屬(包括下屬的下屬…)的所有訂單,也就類似:
Select * from OEHR_ORDERS where SALES_REP_ID IN (‘自己’, ‘下屬’, ‘下屬的下屬…’);
政策實作
政策以Function的方式實作,靈活友善。請檢視以下樣例及注解。這隻是一個樣例實作,實際場景中可以根據具體情況定義邏輯。
create or replace function "F_POLICY_ORDERS_BY_MANAGER" (
schema in VARCHAR2,
tab in VARCHAR2
) return VARCHAR2
is
v_login varchar2(256);
v_conn_user varchar2(256);
predicate varchar2(400);
begin
-- 從APEX會話中擷取目前登入使用者.
v_login := V('APP_USER');
-- 從資料庫連接配接會話中擷取目前資料庫使用者
v_conn_user := SYS_CONTEXT('USERENV','SESSION_USER');
if v_login IN ('HYSUN') OR v_conn_user IN ('SYS') then
-- 允許APEX工作區管理者(這裡是HYSUN)和SYS DBA能夠檢視所有資料
predicate := '1=1';
else
-- 除了APEX工作區管理者和SYS DBA,限制其它所有人隻能檢視自己及下屬的訂單資料
predicate := 'SALES_REP_ID IN (
SELECT employee_id
FROM OEHR_EMPLOYEES
START WITH EMAIL=''' || v_login || '''
CONNECT BY PRIOR employee_id = manager_id
)';
end if;
return predicate;
exception
when no_data_found then
null;
end;
/
政策綁定
将政策綁定到具體的資料庫對象上去。資料庫對象可以是表,也可以是視圖,同義詞。
執行政策綁定需要有DBMS_RLS包的執行權限,如果報沒權限錯誤,需要先授予權限:
GRANT EXECUTE ON DBMS_RLS TO <db_user>;
BEGIN
DBMS_RLS.ADD_POLICY(
object_schema => 'poc',
object_name => 'OEHR_ORDERS',
policy_name => 'query_orders_by_manager',
policy_function => 'F_POLICY_ORDERS_BY_MANAGER',
statement_types => 'SELECT');
END;
/
以上”statement_types”指定了在查詢語句上應用政策,同樣,我們也可以指定為”update”, “delete”等情形。
簡單示範
訂單查詢頁的報表SQL句沒加任何的where條件,如下:
然後用公司最高上司人SKING登入,能看到所有訂單(70條):
再用一個經理 KPARTNER登入,他隻能看到屬于他及下屬的訂單(38條):
說明我們定義的政策根據登入使用者動态的應用到了資料層面,進而有效控制了資料的安全通路。
總結
Oracle VPD能細粒度的控制資料的安全通路,能夠達到行級别。其實通過簡單的增加指定列的政策參數,還能達到列級别的控制(這裡沒作示範,可以檢視具體資料)。
通過 VPD安全控制的對象,不管用什麼管道通路(sqlplus, sql developer, apex, 其它sql用戶端…),得到的結果都是一樣,進而避免了 “應用層面作了資料安全控制,但如果繞過應用層面用其它用戶端通路資料,就沒有資料安全控制“ 的情況,有效增加了資料的安全性。
更多參考資料
https://docs.oracle.com/en/database/oracle/oracle-database/19/dbseg/using-oracle-vpd-to-control-data-access.html