前幾周初略學習了Oracle的VPD技,做了幾個試驗,也在EBS系統上測試了一下。總結如下,有些內容摘自網絡。
在數據庫的數據安全訪問的解決上,有很多的方法來解決權限的問題,常用的方法例如建立視圖的方法控制,例如查詢語句中加where語句來控制。用view的方法在表結構或者權限變更的時候很不容易操作,編碼工作量大、系統適應用戶管理體系的彈性空間較小,一旦權限邏輯發生變動,就可能需要修改權限體系,導致所有的View都必須修改;用where語句可以解決問題但是安全性不好,只能在應用程序級別才能控制,繞開應用程序就無法控制。
Oracle VPD 技術在數據庫級別的安全控制有效的解決了數據訪問操作的權限問題,可以對數據庫對象進行訪問控制,可以靈活的隔離數據,oracle已經實現了VPD,可以直接使用,比在應用層權限控制實現起來較方便,權限維護也比容易。
VPD訪問控制原理也是使用where語句來控制,只是這個where語句是數據庫在操作數據時自動拼接,不是在應用層拼接,而且由事先定義的策略來決定是否拼接條件語句。主要步驟是:
(1) 編寫function, 函數返回拼接在DML語句的where條件之后的語句,但是where語句並不是執行DML時可見的,系統根絕策略自動添加的,條件來自策略函數的返回值。例如:
表:apps.t_policy( T1 VARCHAR2(10 BYTE), T2 NUMBER(10) )
策略函數:
Create or replace function Fn_GetPolicy(
P_Schema In Varchar2,
P_Object In Varchar2)
return varchar2 is
Result varchar2(1000);
begin
Result:='t2 not in (10)';
return(Result);
end Fn_GetPolicy;
/
(2) 在oracle數據庫中添加策略
策略定義在系統中,由DBA維護,應用開發時可根據需要定義策略。例如根據上面的表和策略函數,定義策略如下:
declare
Begin
Dbms_Rls.Add_Policy(
Object_Schema =>'apps', --數據表(或視圖)所在的Schema名稱
Object_Name =>'T_Policy', --數據表(或視圖)的名稱
Policy_Name =>'T_TestPolicy', --POLICY的名稱,主要用於將來對Policy的管理
Function_Schema =>'apps', --返回Where子句的函數所在Schema名稱
Policy_Function =>'Fn_GetPolicy', --返回Where子句的函數名稱
Statement_Types =>'Select', -- DML類型,如 'Select,Insert,Update,Delete'
Enable =>True --是否啟用,值為'True'或'False'
);
end;
/
這樣,在查詢T_Policy這個表的時候,就可以根據策略函數的條件來控制訪問了。
DBMS_RLS內置函數包
Dbms_rls包含很多維護表,視圖,同義詞安全策略的函數,要使用dbms_rls的數據庫用戶必須有sys.dbms_rls的execute權限。常用dbms_rls函數有:
ADD_POLICY 將訪問控制策略添加到對象
DROP_POLICY 刪除對象中的策略
REFRESH_POLICY 重新解析與策略關聯的、緩存的所有語句
ENABLE_POLICY 啟用或禁用策略
CREATE_POLICY_GROUP 創建策略組
ADD_GROUPED_POLICY 將策略添加到策略組
ADD_POLICY_CONTEXT 添加當前應用程序的上下文
DELETE_POLICY_GROUP 刪除策略組
DROP_GROUPED_POLICY 從策略組中刪除一個策略
DROP_POLICY_CONTEXT 刪除活動應用程序的上下文
ENABLE_GROUPED_POLICY 啟用或禁用組策略
DISABLE_GROUPED_POLICY 禁用組策略
REFRESH_GROUPED_POLICY 重新解析與策略組關聯的、緩存的所有語句
最常用的是 add_policy, drop_policy, create_policy_group, add_grouped_policy.
add_policy的參數:
object_schema IN varchar2 null,
object_name IN varchar2,
policy_name IN varchar2,
function_schema IN varchar2 null,
policy_function IN varchar2,
statement_types IN varchar2 null,
update_check IN boolean false,
enable IN boolean true,
static_policy IN boolean false,
policy_type IN binary_integer null,
long_predicate IN in Boolean false,
sec_relevant_cols IN varchar2,
sec_relevant_cols_opt IN binary_integer null
如果想要用策略控制DML訪問表或視圖的某些列,則可以設置sec_relevant_cols 這個參數的值(Oracle 10g的新增內容),默認時就是整個表或視圖都是控制范圍。
VPD差錯控制/調試
在VPD策略執行的時候,最常見的錯誤是"ORA-28113: policy predicate has error","ORA-00936: missing expression"。很多時候都是因為策略函數的返回語句拼接在原DML上面的錯誤,所以能看到完整的語句就可以很快的找到原因。
方法:使用動態性能視圖V$SQLAREA和V$VPD_POLICY。V$SQLAREA包含當前位於共享池中的SQL語句,以及當前的執行統計。視圖V$VPD_POLICY列出當前在數據庫中實施的所有策略,以及謂詞。例如:
select s.sql_text, v.object_name, v.policy, v.predicate
from v$sqlarea s, v$vpd_policy v
where s.hash_value = v.sql_hash;
如果在此查詢中添加一個到V$SESSION的連接,則可以識別哪個用戶正在運行SQL。該方法的不足之處在於:如果數據庫非常忙,則在有機會運行該查詢之前,可能由於其他的SQL命令而在共享池中刷新了當前SQL命令。
