Oracle虛拟私有資料庫(Virtual Private Database,下文簡稱VPD)是Oracle資料庫産品中提供的一個安全功能,它能夠保證Oracle資料庫的多租戶特性,與此同時,可以幫助使用者進行資料庫的整合。
Oracle VPD能夠針對資料庫表和視圖,在行與列級别對資料通路進行控制。從名稱來看,Oracle VPD表達的意思多少有些誤導的嫌疑,畢竟Oracle資料庫已經是一個多使用者的資料庫,每個使用者也許沒有意識到他們正在共享資料庫。是以,将Oracle VPD稱為虛拟私有模式對象(Virtual Private Schema Object,VPSO)更為貼切,因為它會在資料庫内将表、視圖以及同義詞進行虛拟化。但是在本文中,我們還是現将其稱為VPD。
鑒于Oracle的使用者/角色安全權限模型允許通路模式對象,是以VPD将通過通路政策來強制對模式對象資料的細粒度通路。當通路政策開始執行,VPD将會動态地調整SQL語句,如SELECT、UPDATE和INSERT,其方式就是加一個WHERE條件來過濾結果。VPD不僅對使用者是透明的,而且它的安全性是無法被忽視的。在Oracle企業版資料庫産品中,VPD選項還是免費提供的。
在下文要提到的VPD用例中,将介紹它如何在同一個模式下存儲多個公司的資料。
使用Oracle VPD
在許多初創的公司中,口香糖生産公司ABC看到了商機,希望能夠借助托管的業務系統來迅速占領市場。他們決定建立一個客戶資訊系統(CIS)作為集中的網絡托管與資料服務應用。為了讓這個基于雲的SaaS傳遞模型能夠取得成功,他們必須整理一套解決方案,能夠不修改現有的應用代碼,并提供資料安全性保障,并快速地進行測試,将投資回報率最大化。
公司的IT團隊否定了為每個用戶端部署單獨的資料庫政策,因為這樣做無法滿足所有的需求。是以他們開始考慮共享一個單獨的資料庫,其中資料庫負責人建議在同一個資料庫模式下用Oracle VPD存儲多客戶資料。他解釋了VPD對于應用是完全透明的,能夠提供行級資料安全,滿足銷售團隊的靈活性需求,它是最劃算的部署政策。他解釋了客戶為何無法認識到他們在共享一個模式對象。
此外,他還描述了設計的主要元件是如何部署的(表1)。首先,使用者将繼續使用特定用戶端連接配接池作為一個代理,通過現有的Web應用來連接配接到資料庫。當資料庫會話建立之後,一個應用語境将被設定來高效地捕獲用戶端辨別符屬性。安全性通路政策将基于一個政策函數,它将應用到模式對象中以強制用戶端資料的邏輯分離。政策函數将使用應用語境和一個用戶端辨別列來傳回一個條件限制行,通路CIS的表、視圖以及同義詞。
表1:ABC的VPD設定
--以資料庫VPD管理者身份登入
--建立一個應用語境持有用戶端辨別符
create context client_ctx using client_ctx_pkg;
context CLIENT_CTX created.
--建立一個PL/SQL包對應用語境進行設定
create or replace package client_ctx_pkg is procedure set_client_id; end;
/
create or replace package body client_ctx_pkg is procedure set_client_id as client_id number;
begin
select client_id into client_id
from CIS.client where client_name = sys_context('userenv', 'session_user');
dbms_session.set_context('client_ctx', 'client_id', client_id);
exception
when no_data_found then null;
end;
PACKAGE client_ctx_pkg compiled
PACKAGE BODY client_ctx_pkg compiled
--建立一個登入觸發器以運作應用語境PL/SQL包
create trigger set_client_id_ctx_trg after logon on database
client_ctx_pkg.set_client_id;
TRIGGER set_client_id_ctx_trg compiled
--建立一個PL/SQL政策函數來限制資料通路
create or replace function filter_client_data( schema_p in varchar2, table_p in varchar2)
return varchar2
as client_predicate varchar2 (100);
client_predicate := 'client_id = sys_context(''client_ctx'', ''client_id'')';
return client_predicate;
FUNCTION filter_client_data compiled
--基于政策函數建立一個安全性政策并應用到客戶表
dbms_rls.add_policy (object_schema => 'cis'
,object_name => 'customer'
,policy_name => 'client_policy'
,function_schema => 'vpd_admin'
,policy_function => 'filter_client_data'
);
anonymous block completed
設定好了,VPD現在可以動态地添加條件到每一個查詢,并高效地過濾每一個用戶端的資料(表2)。
表2:ABC運作VPD
--1.作為一個Big Bubble Company使用者,選擇你的客戶
select customer_name from CIS.customer;
CUSTOMER_NAME
------------------------------
The Gum Shop
Jaime’s Candy
Shannon’s Pharmacy
-- 2. 作為一個Chew IT Enterprises 使用者,選擇你的客戶
Sweet Tooth
Gum Emporium
--确認VPD動态添加一個條件到每個查詢
explain plan
set statement_ID = 'XXX'
for select * from CIS.customer;
select * from table(dbms_xplan.display('PLAN_TABLE','XXX','TYPICAL'));
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 2 | 60 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| CUSTOMER | 2 | 60 | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("CLIENT_ID"=TO_NUMBER(SYS_CONTEXT('client_ctx','client_id')))
本文轉自 wws5201985 51CTO部落格,原文連結:http://blog.51cto.com/wws5201985/775951,如需轉載請自行聯系原作者