Oracle策略的使用(dbms_rls.add_policy)

       数据访问控制权限,是一个在实际项目中用得很平常的问题。比如公司部门,就工资来说,本人只能看到自己的工资信息,不能看到其他同事的信息,部门经理或更高级别的人可以看到他对应权限的信息,看到这里大多数人会选择在View加上Where子句来进行数据隔离。此方法编码工作量大、系统适应用户治理体系的弹性空间较小,一旦权限逻辑发生变动,就可能需要修改权限体系,导致所有的View都必须修改。除了这种实现,可以采用Oracle的policy功能来实现。具体实现方式如下:

Oracle Policy的简单说明:
  Policy应用于数据行访问权限控制时,其作用简而言之,就是在查询数据表时,自动在查询结果上加上一个Where子句。假如该查询已有where子句,则在该Where子句后面加上"And ..."。
  由Oracle Policy自动加入的Where子句的内容,通常由一个函数来实现。而进行数据行访问权限控制算法实现的结果,也是通过该函数返回。

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',
       object_name=>'emp',
       policy_name=>'emp',
       function_schema=>'scott',
       policy_function=>'FN',
       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',
       object_name=>'emp',
       policy_name=>'emp',
       enable=>true
  );
end;
删除策略:

begin
  dbms_rls.drop_policy(
       object_schema=>'scott',
       object_name=>'emp',
       policy_name=>'emp'
  );
end;
这样就可以实现数据的查询权限控制了。












  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小老虎Love

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值