Oracle策略的使用(dbms_rls.add_policy)
数据访问控制权限,是一个在实际项目中用得很平常的问题。比如公司部门,就工资来说,本人只能看到自己的工资信息,不能看到其他同事的信息,部门经理或更高级别的人可以看到他对应权限的信息,看到这里大多数人会选择在View加上Where子句来进行数据隔离。此方法编码工作量大、系统适应用户治理体系的弹性空间较小,一旦权限逻辑发生变动,就可能需要修改权限体系,导致所有的View都必须修改。除了这种实现,可以采用Oracle的policy功能来实现。具体实现方式如下: Oracle Policy的简单说明: Oracle Policy语法说明: 创建策略:
begin -- Call the procedure dbms_rls.add_policy(object_schema => :数据表(或视图)所在的Schema名称/用户,object_name => :数据表(或视图)的名称,policy_name => :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',static_policy => 默认值为FALSE。如果它被设置为TRUE则所有用户启用该策略,sys或特权用户例外。 policy_type => :默认值是null,意味着static_policy的值决定,在这里指定任何策略将覆盖static_policy的值。 long_predicate => long_predicate,sec_relevant_cols => :敏感的字段名称,sec_relevant_cols_opt => :设置为dbms_rls.ALL_ROWS来显示所有的行,敏感的列的值为null); end; 删除策略: begin dbms_rls.drop_policy( object_schema=>'要删除的Policy所在的Schema',object_name=>'要删除Policy的数据表(或视图)名称',policy_name=>'要删除的Policy名称' ); end; 改变policy状态: begin dbms_rls.enable_policy( object_schema=>'要改变的Policy所在的Schema',object_name=>'要改变Policy的数据表(或视图)名称',policy_name=>'要删除的Policy名称',enable=>'默认True,是否启用,True为启用策略,False为禁用策略' ); end; 需要注意,在普通用户下是没有dbms_rls的权限,在使用之前需要对其受权 grant execute,debug on dbms_rls to scott;具体实现: 在创建策略时需要创建策略使用到的函数: create or replace function FN(p_schema in varchar2 default NULL,p_object in varchar2 default NULL) return varchar2 as begin return 'deptno=10'; end;创建一个策略,只能看到部门为10的数据: begin dbms_rls.add_policy( object_schema=>'scott',object_name=>'emp',policy_name=>'emp',function_schema=>'scott',policy_function=>'FN',statement_types=>'SELECT' ); end; 执行结果: EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7782 CLARK MANAGER 7839 1981/6/9 2450.00 10 7934 MILLER CLERK 7782 1982/1/23 1300.00 10只显示部门为10的数据。 如果该用户可以看到自己部门信息,也可以看到其他部门的部分信息,一些敏感字段则不能看到,比如工资。根据上个策略,只增加两个条件即可,如下: begin dbms_rls.add_policy( object_schema=>'scott',statement_types=>'SELECT',sec_relevant_cols=>'sal',sec_relevant_cols_opt=>dbms_rls.ALL_ROWS ); end;执行结果: EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7369 SMITH CLERK 7902 1980/12/17 20 7499 ALLEN SALESMAN 7698 1981/2/20 300.00 30 7521 WARD SALESMAN 7698 1981/2/22 500.00 30 7566 JONES MANAGER 7839 1981/4/2 20 7654 MARTIN SALESMAN 7698 1981/9/28 1400.00 30 7698 BLAKE MANAGER 7839 1981/5/1 30 7782 CLARK MANAGER 7839 1981/6/9 2450 10 7788 SCOTT ANALYST 7566 1987/4/19 20 7844 TURNER SALESMAN 7698 1981/9/8 0.00 30 7876 ADAMS CLERK 7788 1987/5/23 20 7900 JAMES CLERK 7698 1981/12/3 30 7902 FORD ANALYST 7566 1981/12/3 20 7934 MILLER CLERK 7782 1982/1/23 1300 10所有记录全部显示,只是配置了敏感字段的sal,不是部门为10的数据则显示为空。 改变策略状态: begin dbms_rls.enable_policy( object_schema=>'scott',enable=>true ); end;删除策略: begin dbms_rls.drop_policy( object_schema=>'scott',policy_name=>'emp' ); end;这样就可以实现数据的查询权限控制了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |