使用Oracle VPD(Virtual Private Database)實現資料庫層面資料許可權

realkid4發表於2014-04-03

 

在應用系統開發領域,功能許可權和資料許可權兩層許可權體系佔到了安全功能性需求的大半。除了在應用程式層面進行處理之外,我們其實還可以從資料庫層面實現資料許可權訪問的。

Oracle VPDVirtual Private Database)就是從資料庫層面實現資料訪問控制的一種成熟技術。藉助VPD,一些已經上線或者不容易進行二次開發的功能可以比較容易的解決。

 

1VPD簡述

 

從產品屬性來看,Oracle Virtual Private Database(簡稱VPD)是歸屬在Oracle安全security框架下的成熟產品。要注意:VPD是企業版Enterprise版本功能,在其他如標準Standard版下是不能使用的。

簡單的說,VPD就是介於使用者SQL語句和實際執行物件之間的介質層。使用者或者應用程式發出的SQL語句在傳入到DBMS執行之前,會自動被攔截並且進行額外處理。處理的結果往往反映為在語句where條件中新增特殊的條件式。

例如:資料表T中包括了所有供應商的資訊,設計者系統任何SQL語句傳送之後,都只能檢視到location=’北京’的記錄。在沒有VPD的情況下,我們必須修改應用程式程式碼,將location=’北京’加入到所有對應資料表操作SQL語句中。

藉助VPD,應用程式不需要修改任何程式碼。我們只需要在資料庫層面設定一個指定策略規則,如果針對某個資料物件表的所有SQL語句,都會呼叫一個設定的函式。函式自身會返回一個字串條件,作為補充的where語句條件。

例如:如果我們設定對資料表t的每個Select語句都要新增一個條件object_id<100,那麼即使應用層發出了select * from t,那麼實際執行的也都是select * from t where object_id<100

下面我們透過一系列的實驗來進行驗證演示。

 

2、環境介紹和配置

 

我們選擇Oracle 11g企業版進行測試。

 

SQL> select * from v$version;

 

BANNER

-----------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - Production

PL/SQL Release 11.2.0.4.0 - Production

CORE 11.2.0.4.0 Production

 

注意:只有在其中明確標註Enterprise Edition才認為是企業版Oracle。否則是標準版。

建立專門使用者用於實驗。

 

SQL> create user vpd identified by vpd;

User created

 

SQL> grant resource, connect to vpd;

Grant succeeded

 

SQL> grant execute on dbms_rls to vpd;

Grant succeeded

 

SQL> grant select any dictionary to vpd;

Grant succeeded

 

vpd schema下建立資料表T

 

SQL> conn vpd/vpd@ora11g;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as vpd

 

SQL> create table t as select * from dba_objects;

Table created

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

     86032

 

目標是使用VPD實現資料隱藏:只有VPD使用者查詢資料表T才能獲取全文,其他schema讀取不到其中資料。

 

3、配置VPD

 

配置VPD第一步是定義處理函式,我們需要函式的意義是返回一個字串條件列。在函式中,我們可以根據不同的情況插入自由的邏輯。

 

針對這個需求,首先需要獲取到查詢使用者的schema名稱才能判斷。於是,函式為:

 

SQL> create or replace function f_limit_access

  2  (

  3     vc_schema varchar2,

  4     vc_object varchar2

  5  ) return varchar2

  6  as

  7  vc_userid varchar2(100);

  8  begin

  9    select SYS_CONTEXT('USERENV','SESSION_USER')

 10    into vc_userid

 11    from dual;

 12 

 13    if (trim(vc_userid)='VPD') then

 14       return '1=1';

 15    else

 16       return '1=0';

 17    end if;

 18 

 19  end;

 20  /

 

Function created

 

sys_context函式可以獲取到當前使用者名稱資訊,做出判斷。輸入引數vc_schemavc_object是作為呼叫點,可以逆向插入回去的。

第二步,使用dbms_rls函式包建立訪問策略policy

 

SQL> exec dbms_rls.add_policy(object_schema => 'VPD',object_name => 'T',policy_name => 'VPD_TEST',function_schema => 'VPD',policy_function => 'F_LIMIT_ACCESS');

 

PL/SQL procedure successfully completed

 

注意:這其中引數含義為:object_schema表示希望給schema物件新增policyobject_name為具體哪個物件。policy_name表示策略的名稱。function_schemapolicy_function表示處理函式所在的schema和函式名稱。

檢視user_policies可以檢視到當前schema下策略資訊。

 

SQL> select policy_name, SEL, INS, UPD, DEL, IDX, CHK_OPTION, ENABLE from user_policies;

 

POLICY_NAME                    SEL INS UPD DEL IDX CHK_OPTION ENABLE

------------------------------ --- --- --- --- --- ---------- ------

VPD_TEST                       YES YES YES YES NO  NO         YES

 

此時使用者為vpd,檢視資料T結果如下:

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

     86032

 

切換到另一個使用者,雖然有訪問資料表許可權,但是結果變化。

 

--sys下執行

SQL> grant select any table to scott;

Grant succeeded

 

SQL> conn scott/tiger@ora11g

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as scott

 

SQL> select count(*) from vpd.t;

 

  COUNT(*)

----------

         0

 

即使是system這樣的高許可權使用者,結果一樣。

 

SQL> alter user system identified by oracle;

User altered

 

SQL> conn system/oracle@ora11g;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as system

 

SQL> select count(*) from vpd.t;

  COUNT(*)

----------

         0

 

但是,唯獨對sys使用者,所有的policy是失效的,這也就是VPD的一個特點和問題。

 

SQL> conn sys/oracle@ora11g as sysdba

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as SYS

 

SQL> select count(*) from vpd.t;

 

  COUNT(*)

----------

     86032

 

4、結論

 

作為早期Oracle提供的一種資料安全策略,VPD在應用和資料庫之間建立了插入語句屏障。在沒有辦法修改程式碼的情況下,一些簡單的資料許可權需求是可以透過VPD解決的。

但是,也要看到VPD的侷限性,比如sys訪問,安全策略容易被攻破等。這些都可以使用更高階的Oracle策略外加應用程式、管理手段進行彌補,實現相對的安全。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-1135651/,如需轉載,請註明出處,否則將追究法律責任。

相關文章