Chinaunix首页 | 论坛 | 博客
  • 博客访问: 64492
  • 博文数量: 22
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-16 21:39
文章分类

全部博文(22)

文章存档

2010年(3)

2009年(11)

2008年(8)

我的朋友

分类: Oracle

2009-06-05 09:25:26

/*-----------------------------------------------------------------
    採用oracle的dbms_rls包實現數據訪問控制
    在大部份系統中,權限控制主要定義為模塊進入權限的控制和數據列訪問權限的控制(如:某某人可以進入某個控制,
倉庫不充許查看有關部門的字段等等)。但在某些系統中,權限控制又必須定義到數據行訪問權限的控制,
此需求一般出現在同一系統,不同的相對獨立機構使用的情況。(如:集團下屬多個子公司,所有子公司使用同一套數據表,
但不同子公司的數據相對隔離), 絕大多數人會選擇在View加上Where子句來進行數據隔離。此方法編碼工作量大、
系統適應用戶管理體系的彈性空間較小,一旦權限邏輯發生變動,就可能需要修改權限體系,導致所有的View都必須修改。
    本文探討的使用Oracle提供的Policy管理方法來實現數據行的隔離
    注意:這裡的policy是在9i上測試,8i的policy是不同9i的,但是原理是一樣的.
------------------------------------------------------------------*/
--  (1)建立測試數據表(t_policy):
create table t_policy
(
  t1 varchar2(10),
  t2 number(10)
);
insert into t_policy values('a',10);
insert into t_policy values('b',20);
insert into t_policy values('c',30);
commit;

--  (2)建立測試policy的函數:
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)';   --  此子句將被加載於啟用了該Policy的DML語言之後
  return(result);
end fn_getpolicy;


--  (3)加入policy:
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,insert,update,delete', --要使用該policy的dml類型,如'select,insert,update,delete'
          update_check =>true, --僅適用於statement_type為'insert,update',值為'true'或'false'
          enable =>true    --是否啟用,值為'true'或'false'
  );
end;
--註:如果update_check設為'true',則用戶插入的值不符合policy_function返回條件時,該dml執行返回錯誤信息。

--  現在就可以工作了:
select * from t_policy;
--看看結果怎樣, 是不是少了t2=10這項了.


--  (4)刪除policy
declare
begin
  dbms_rls.drop_policy('niegc','t_policy','t_testpolicy');
end;


--  (5)設置policy的狀態
declare
begin
  dbms_rls.enable_policy('niegc','t_policy','t_testpolicy',false);
end;


再附上一段,查詢SO時,智能看到自己Sales Order的Policy:
create or replace function ssak.db_data_policy(p_schema in varchar2,p_object in varchar2) return varchar2 is
  x_result varchar2(1000);
  x_user_id number;
begin
  x_user_id:=apps.fnd_global.user_id();
  if p_object='OE_ORDER_HEADERS_V' then
    x_result:='created_by=' || x_user_id;
  else
    x_result:=null;   
  end if;
  --  此子句將加載於啟用了該Policy的DML語言之後
  return(x_result);
end db_data_policy;

阅读(1395) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~