使用Virtual Private Database實現細粒度訪問控制

pxbibm發表於2015-07-20

資料安全一直應用系統開發的重點,Oracle VPDVirtual Private Database)就是從資料庫層面實現資料訪問控制的一種成熟技術。藉助VPD,一些已經上線或者不容易進行二次開發的功能可以比較容易的解決。Virtual Private Database,虛擬專有資料庫,簡稱VPD,能夠利用一系列的安全策略函式控制使用者對於一張表上行級或者列級的資料的訪問,除了表之外還可以應用於View或者Synonym。 

1VPD簡述

 

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

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

例如:資料表T中包括了所有員工的通訊資訊,當每個員工登陸HR系統時,能查詢到所有的員工通訊資訊。但是現在業務需求變了,當員工登陸HR系統後,應該只能查到自己的資訊。在沒有VPD的情況下,我們必須修改應用程式程式碼,將username=’自己的名字’加入到所有對應資料表操作SQL語句中。業務邏輯應該如下:
限制使用者只能從T表中查詢到和自己使用者名稱匹配的記錄,例如:A使用者登陸後,執行select * from T,在VPD的作用下,相當於為這條語句增加了一個隱含的條件where username='A',等於執行了select * from T where username='A'僅返回符合username='A'這一條件的記錄.
 

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

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

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

 

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;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as vpd

 

SQL> create table t as select * from dba_users;

Table created

 

SQL> select count(*) from t;

 

  COUNT(*)

----------

     14

 

目標是使用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    return 'username='''||vc_userid||'''';

 13 

 14  end;

 25  /

 

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 username,user_id from t;

 

  USERNAME        USER_ID

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

     VPD            40

 

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

 

--sys下執行

SQL> grant select any table to scott;

Grant succeeded

 

SQL> conn scott/tiger

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as scott

 

SQL> select username,user_id from t;

 

  USERNAME        USER_ID

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

     SCOTT            35

 

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

 

SQL> alter user system identified by oracle;

User altered

 

SQL> conn system/oracle;

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as system

 

SQL> select username,user_id from t;

 

  USERNAME        USER_ID

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

     SYSTEM            5

 

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

 

SQL> conn sys/oracle as sysdba

Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.4.0

Connected as SYS

 

SQL> select username,user_id from vpd.t;

USERNAME                 USER_ID
------------------- ---------------------
SYSADMIN_VPD              36
SYS                        0
SYSTEM                     5
SCOTT                     35
VPD                       40
SPA_TEST_USER             39
OWOODS                    38
TBROOKE                   37
OUTLN                     11
DBSNMP                    24
WMSYS                     26

USERNAME                 USER_ID
--------------------- -------------------
APPQOSSYS                 34
DIP                       19
ORACLE_OCM                25

14 rows selected.

 

4、結論

 

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

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


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

相關文章