天天看點

oracle column的設定,oracle實驗-設定基于Column - Level 的VPD

設定基于Column - Level 的VPD

從Oracle 10g開始,我們可以設定基于column-level的VPD,進而保護那些資料表中的重要資訊列,比如password column、Price等(這個要根據具體的應用需求來定),有兩種column-level的方法可以使用:

1)使用column-level VPD 保護資料不被通路

2)Display the column with NULL values

說明:1)一個查詢中包含被保護的column

2)和基于row-based VPD有所不同,在column-level VPD中,所有的行均可以被通路,但是被保護列可以被隔離或采用MASK顯示。

3)column-level VPD在表和視圖上均可設定

實作:和row-based VPD相似,我們隻需在調用dbms_rls.add_policy的時候,指定sec_relevant_cols(指定被保護列),sec_relevant_cols_opt(MASK)兩個參數即可.

下面我通過一個test case來簡單的介紹一下

需求說明:

對于study.customer 表中的status 字段,不允許維護帳戶(user_a,user_b)檢視或顯示為NULL。

實作過程

1)建立測試表、使用者,并授予相應的權限

--建表

create table study.customer

(region varchar2(4),

msisdn varchar2(11),

status varchar2(2)

);

--插入資料

insert into study.customer values('530','13905301234','0');

insert into study.customer values('530','13905305678','1');

insert into study.customer values('531','13805318888','0');

insert into study.customer values('531','13605319999','1');

insert into study.customer values('532','15805320000','0');

insert into study.customer values('533','15905336666','0');

commit;

--授權

create user user_a identified by user_a default tablespace data_01;

create user user_b identified by user_b default tablespace data_01;

grant create session to user_a,user_b;

grant select,insert,update,delete on study.customer to user_a,user_b;

grant execute on dbms_rls to user_a,user_b;

2)建立一個security package,并授權

create or replace package study.security_pkg as

function test_security(owner varchar2,objname varchar2) return varchar2;

end;

/

create or replace package body study.security_pkg is

function test_security(owner varchar2,objname varchar2) return varchar2 is

v_sql varchar2(2000):='1=0';

begin

if (sys_context('USERENV','SESSION_USER') ='STUDY') then

v_sql:=null;

end if;

return v_sql;

end;

end;

/

grant execute on study.security_pkg to public;

create or replace public synonym security_pkg for study.security_pkg;

3)設定policy

begin

dbms_rls.add_policy(

object_schema => 'STUDY',

object_name => 'CUSTOMER',

policy_name => 'C_COL_POLICY',

function_schema => 'STUDY',

policy_function => 'SECURITY_PKG.TEST_SECURITY',

sec_relevant_cols => 'STATUS');

end;

/

--在這個security policy 設定中,我們指定了status列是被保護的列,所有的維護帳戶不能通路該列,否則将傳回0行。

4)測試column-level VPD

下面我們來感受一下吧(user_a,user_b是受限的維護帳戶,看看效果)

SQL> conn user_a/user_a

已連接配接。

SQL> select * from study.customer;

未標明行

SQL> select region,msisdn from study.customer;

REGI MSISDN

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

530  13905301234

530  13905305678

531  13805318888

531  13605319999

532  15805320000

533  15905336666

已選擇6行。

SQL> select msisdn,status from study.customer;

未標明行

SQL> conn user_b/user_b

已連接配接。

SQL> select * from study.customer;

未標明行

SQL> select region,msisdn from study.customer;

REGI MSISDN

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

530  13905301234

530  13905305678

531  13805318888

531  13605319999

532  15805320000

533  15905336666

已選擇6行。

SQL> select msisdn,status from study.customer;

未標明行

SQL> conn study/study

已連接配接。

SQL> select * from study.customer;

REGI MSISDN      ST

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

530  13905301234 0

530  13905305678 1

531  13805318888 0

531  13605319999 1

532  15805320000 0

533  15905336666 0

已選擇6行。

SQL> select msisdn,status from study.customer;

MSISDN      ST

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

13905301234 0

13905305678 1

13805318888 0

13605319999 1

15805320000 0

15905336666 0

已選擇6行。

SQL>

5)補充說明

一、如果要保護多列,我們隻需要在sec_relevant_cols參數中指定多個列即可(用,分開),比如

begin

dbms_rls.add_policy(

object_schema => 'STUDY',

object_name => 'CUSTOMER',

policy_name => 'C_COL_POLICY',

function_schema => 'STUDY',

policy_function => 'SECURITY_PKG.TEST_SECURITY',

sec_relevant_cols => 'MSISDN,STATUS');

end;

/

二、如果要采用masking option,我們隻需要在設定policy的時候,指定sec_relevant_cols_opt 參數為DBMS_RLS.ALL_ROWS即可,比如:

begin

dbms_rls.add_policy(

object_schema => 'STUDY',

object_name => 'CUSTOMER',

policy_name => 'C_COL_POLICY',

function_schema => 'STUDY',

policy_function => 'SECURITY_PKG.TEST_SECURITY',

sec_relevant_cols => 'STATUS',

sec_relevant_cols_opt => dbms_rls.all_rows);

end;

/

在這種保護模式下,被保護的列,均顯示是NULL。

三、同樣的如果我們需要保護涉及到該列的DML操作時,需要設定如下2個參數(前面的row-based VPD中已經介紹過了)

begin

dbms_rls.add_policy(

object_schema => 'STUDY',

object_name => 'CUSTOMER',

policy_name => 'C_COL_POLICY',

function_schema => 'STUDY',

policy_function => 'SECURITY_PKG.TEST_SECURITY',

statement_types => 'SELECT,INSERT,UPDATE,DELETE',

update_check => TRUE,

sec_relevant_cols => 'STATUS');

end;

/

四、masking option隻支援查詢操作,對DML操作無效

五、捎帶說一下

如果要删除一個policy,可以通過dbms_rls.drop_policy完成,如

begin

dbms_rls.drop_policy (object_schema =>'STUDY', object_name =>'CUSTOMER', policy_name=> 'C_COL_POLICY');

end;

/

如果要enable/disable一個policy可以通過dbms_rls.enable_policy完成,如

SQL> exec dbms_rls.enable_policy('STUDY','CUSTOMER','C_COL_POLICY',FALSE);

PL/SQL procedure successfully completed

SQL> exec dbms_rls.enable_policy('STUDY','CUSTOMER','C_COL_POLICY',TRUE);

PL/SQL procedure successfully completed

SQL>

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