DBMS_RLS包实现数据库表中的行级安全控制

DBMS_RLS 实现一个数据库表为行级安全控制,该套餐包括细粒度的访问控制管理界面,此接口是用来实现VPD(Virtual Private Database),虚拟专用数据库。DBMS_RLS仅仅能在ORACLE的企业版(Enterpris Edition Only)本才干够用。oracle ebs 的权限是用这个来管理的。

在数据库的数据安全訪问的解决上,有非常多的方法来解决权限的问题。有的是通过功能模块来控制訪问权限的,有的是用建立视图的方法控制,比如查询语句中加where语句来控制。可是用view的方法时,当表结构或者权限变更的时候就非常不easy操作,编码工作量大、系统适应用户管理体系的弹性空间较小,一旦权限逻辑发生变动,就可能须要改动权限体系,导致全部的View都必须改动;用where语句能够解决这个问题可是安全性不好,仅仅能在应用程序级别才干控制。绕开应用程序就无法控制。

Oracle VPD 技术在数据库级别的安全控制有效的攻克了数据訪问操作的权限问题,能够对数据库对象进行訪问控制,能够灵活的隔离数据,oracle已经实现了VPD,能够直接使用。比在应用层权限控制实现起来较方便,权限维护也比easy。

VPD訪问控制原理也是使用where语句来控制,仅仅是这个where语句是数据库在操作数据时自己主动拼接,不是在应用层拼接,并且由事先定义的策略来决定是否拼接条件语句。


以下我来用DBMS_RLS的包来实现例如以下条件的訪问控制功能:
有例如以下4个用户AM145,AM147,AM148,AM149
1,仅仅能查询OE.CUSTS表,
2,其过滤条件是OE.CUSTS.account_mgr_id=substr(user,3,3)

 

第一步:创建用户及訪问授权
$>sqlplus / as sysdba
create user AM145 identified by AM145;
grant create session to AM145;
grant select on oe.custs to AM145;
create user AM147 identified by AM147;
grant create session to AM147;
grant select on oe.custs to AM147;
create user AM148 identified by AM148;
grant create session to AM148;
grant select on oe.custs to AM148;
create user AM149 identified by AM149;
grant create session to AM149;
grant select on oe.custs to AM149;

 

第二步:创建function获得where 过滤条件的predicate.函数返回拼接在DML语句的where条件之后的语句,可是where语句并非运行DML时可见的,系统根绝策略自己主动加入的,条件来自策略函数的返回值。


vi fun1.sql
create or replace FUNCTION oe.policy_function (object_schema IN VARCHAR2, object_name VARCHAR2)
        RETURN VARCHAR2 IS
ls_return varchar2(100);
ls_username varchar2(100);
begin
        ls_username := user;
        if ls_username like 'AM%' then
                ls_return := 'oe.custs.account_mgr_id=substr('||''''||ls_username||''''||',3,3)';
        end if;
        return ls_return;
end;
/

SQL> @fun1.sql

Function created.


第三步:加入策略
vi myPolicy1.sql
BEGIN
dbms_rls.add_policy(object_schema => 'oe',
object_name => 'custs',
policy_name => 'my_policy1',
function_schema =>'oe',
policy_function => 'policy_function',
statement_types =>'select',
enable=>true);
END;
/

SQL> @myPolicy1.sql

PL/SQL procedure successfully completed.


第四步:验证是否成功
SQL> select account_mgr_id,count(*) from oe.custs group by account_mgr_id;

ACCOUNT_MGR_ID   COUNT(*)
-------------- ----------
           147         76
           149         74
           148         58
           145        111


SQL> conn AM145/AM145
Connected.
SQL> select count(*) from oe.custs;

  COUNT(*)
----------
       111

SQL> conn AM147/AM147
Connected.
SQL>  select count(*) from oe.custs;

  COUNT(*)
----------
        76

SQL> conn AM148/AM148
Connected.
SQL>  select count(*) from oe.custs;

  COUNT(*)
----------
        58

SQL> conn AM149/AM149
Connected.
SQL>  select count(*) from oe.custs;

  COUNT(*)
----------
        74

从上面能够看出,对用户AM145,AM147,AM148,AM149的訪问控制成功。

 

Note:删除策略:
SQL> CONN / AS SYSDBA
Connected.
SQL> exec DBMS_RLS.DROP_POLICY('oe', 'CUSTS', 'my_policy1');

PL/SQL procedure successfully completed.

SQL> conn AM145/AM145
Connected.
SQL> select count(*) from oe.custs;

  COUNT(*)
----------
       319
删除策略后用户AM145,AM147,AM148,AM149是能够看OE表的全部的行数据的。

 

版权声明:本文博主原创文章,博客,未经同意不得转载。

posted @ 2015-10-17 14:51  hrhguanli  阅读(399)  评论(0编辑  收藏  举报