前言 數據訪問權限控制
是一個古老而又實際的問題
在大部份系統中
權限控制主要定義為模塊進入權限的控制和數據列訪問權限的控制(如
某某人可以進入某個控制
倉庫不充許查看有關金額的字段等等)
但在某些系統中
權限控制又必須定義到數據行訪問權限的控制
此需求一般出現在同一系統
不同的相對獨立機構使用的情況
(如
集團下屬多個子公司
所有子公司使用同一套數據表
但不同子公司的數據相對隔離)
當然
絕大多數人會選擇在View加上Where子句來進行數據隔離
此方法編碼工作量大
系統適應用戶管理體系的彈性空間較小
一旦權限邏輯發生變動
就可能需要修改權限體系
導致所有的View都必須修改
本文探討的使用Oracle提供的Policy管理方法來實現數據行的隔離
特別感謝Javac兄提出的此解決方案!
實現 Oracle Policy的簡單說明
Policy應用於數據行訪問權限控制時
其作用簡而言之
就是在查詢數據表時
自動在查詢結果上加上一個Where子句
如果該查詢已有where子句
則在該Where子句後面加上
And
由Oracle Policy自動加入的Where子句的內容
通常由一個函數來實現
而進行數據行訪問權限控制算法實現的結果
也是通過該函數返回
Oracle Policy的語法簡述
新增Policy
Dbms_Rls
Add_Policy(Object_Schema
數據表(或視圖)所在的Schema名稱
Object_Name
數據表(或視圖)的名稱
Policy_Name
POLICY的名稱
主要用於將來對Policy的管理
Function_Schema
返回Where子句的函數所在Schema名稱
Policy_Function
返回Where子句的函數名稱
Statement_Types
要使用該Policy的DML類型
如
Select
Insert
Update
Delete
Update_Check
僅適用於Statement_Type為
Insert
Update
值為
True
或
False
Enable
是否啟用
值為
True
或
False
);
注
如果Update_Check設為
True
則用戶插入的值不符合Policy_Function返回條件時
該DML執行返回錯誤信息
刪除Policy
Dbms_Rls
drop_policy(object_schema
要刪除的Policy所在的Schema
object_name
要刪除Policy的數據表(或視圖)名稱
policy_name
要刪除的Policy名稱
);
設定Policy狀態
Dbms_Rls
Enable_Policy(object_schema
要刪除的Policy所在的Schema
object_name
要刪除Policy的數據表(或視圖)名稱
policy_name
要刪除的Policy名稱
Enable
是否啟用
值為
True
或
False
);
Policy使用特性及使用建議
● 一個數據表(或視圖)可以有多個Policy
但Policy的名稱在整個Schema范圍內不允許重復
● 如果將Policy指定到視圖
則刪除Policy後
應重新編譯該視圖
否則User_Updatable_Columns系統字典表返回的是否可新增修改刪除的信息可能會全部為
NOT
● 通過Policy可以限制用戶對數據表記錄的操作范圍
如果Policy加在數據表
則由於前台涉及的數據源(通常是視圖)往往涉及許多張數據表
權限控制難度很大
建議將Policy加在視圖
Oracle Policy 應用實例
創建測試數據表
Create Table T_Policy(T
Varchar
(
)
T
Number(
));
創建測試的Policy函數
CREATE OR REPLACE Function Fn_GetPolicy (P_Schema In Varchar
P_Object In Varchar
)
Return Varchar
Is
Begin
Return
T
=
;
End;
插入測試數據
Insert Into T_Policy Values(
a
);
Insert Into T_Policy Values(
b
);
Insert Into T_Policy Values(
c
);
Commit;
加入Policy
Begin
Dbms_Rls
Add_Policy(Object_Schema =>
Scott
Object_Name =>
T_Policy
Policy_Name =>
T_TestPolicy
Function_Schema =>
Scott
Policy_Function =>
Fn_GetPolicy
Statement_Types =>
Select
Insert
Update
Delete
Update_Check =>
True
Enable =>
True
);
End;
測試Policy
Select * From T_Policy;
Insert Into T_Policy Values (
d
);
Insert Into T_Policy Values (
d
);
Commit;
查看Policyy設定情況
Select * From user_policies;
重要提示
執行Dbms_Rls
Add_Policy時
必須將執行Dbms_Rls包執行的權限授予Scott
測試時也可能使用其它Schema
最簡單的方法是將測試的Schame設為
DBA
權限
From:http://tw.wingwit.com/Article/program/Oracle/201311/16724.html