[Oracle] 数据库安全之 - 虚拟私有数据库 (VPD)

Oracle的安全分为四大部分,分别是用户管理、访问控制、数据保护和监控,具体可参考《[Oracle] 数据库安全概述》http://blog.csdn.net/u010415792/article/details/9008089

今天着重讲讲访问控制中一种常见的技术VPD,VPD的全称是Virtual Private Database 虚拟私有数据库,它在Oracle 8i时就出现了,是Oracle比较早期的一种数据安全手段。

它是指通过指定策略,对用户的SQL自动添加过滤谓词,以达到对结果集进行过滤的目的,其示意图如下:

[Oracle] 数据库安全之 - 虚拟私有数据库 (VPD)_第1张图片


其大致过程如下:用户发出SQL语句访问表中数据,此时触发定义在该表上的安全策略,该安全策略会在相应的列上加上Where谓词条件,最终返回给用户的是过滤后的结果集。这样用户只能看到自己有权限看到的数据,其效果如下图所示:

[Oracle] 数据库安全之 - 虚拟私有数据库 (VPD)_第2张图片


用户1和用户2虽然发出了两个一模一样的SQL语句,但根据相应的安全策略,他们得到的结果有可能不一样,就像访问自己私有的数据库一样,这也是为什么这项技术叫虚拟私有数据库。下面看几个例子:

1)首先,创建一个函数,该函数定义要加哪些谓词条件:

SQL> create or replace function hide_sal_comm(v_schema varchar2, v_object varchar2)
  2  return varchar2 as con varchar2(200);
  3  begin
  4  con:='deptno=30';
  5  return(con);
  6  end hide_sal_comm;
  7  /

函数已创建。

2)利用dmbs_rls.add_policy()添加一个安全策略,在policy_function中指定上一步创建的函数,在sec_relevant_cols中指定要过滤的字段:

SQL> begin
  2     dbms_rls.add_policy(
  3       object_schema          => 'scott',
  4       object_name            => 'emp',
  5       policy_name            => 'hide_sal_policy',
  6       policy_function        => 'hide_sal_comm',
  7       sec_relevant_cols      => 'sal,comm');
  8  end;
  9  /

PL/SQL 过程已成功完成。

3)添加安全策略后,现在访问该表,发现只能获得deptno=30的数据:

SQL> select * from scott.emp;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7900 JAMES      CLERK           7698 03-12月-81            950                    30

已选择6行。

4)这里要注意的是,只有当访问安全策略中指定字段时,安全策略才起作用,如果select的字段中不包含这些字段,安全策略是不会起作用的:

SQL> select ename,deptno from scott.emp;

ENAME          DEPTNO
---------- ----------
SMITH              20
ALLEN              30
WARD               30
JONES              20
MARTIN             30
BLAKE              30
CLARK              10
SCOTT              20
KING               10
TURNER             30
ADAMS              20

ENAME          DEPTNO
---------- ----------
JAMES              30
FORD               20
MILLER             10

已选择14行。

5)上面定义的安全策略有个缺点,就是会把所有的字段都隐藏,如果你只想隐藏敏感字段,可以设置sec_relevant_cols_opt:

SQL> exec dbms_rls.drop_policy('scott','emp','hide_sal_policy');

PL/SQL 过程已成功完成。

SQL> begin
  2     dbms_rls.add_policy(
  3       object_schema          => 'scott',
  4       object_name            => 'emp',
  5       policy_name            => 'hide_sal_policy',
  6       policy_function        => 'hide_sal_comm',
  7       sec_relevant_cols      => 'sal,comm',
  8      sec_relevant_cols_opt  => dbms_rls.ALL_ROWS);
  9  end;
 10  /

PL/SQL 过程已成功完成。

6)这时再执行同样的语句,可以发现返回所有行,只是敏感字段的数据被隐藏了(就好像NULL一样):

SQL> select * from scott.emp order by deptno;

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7782 CLARK      MANAGER         7839 09-6月 -81                                   10
      7839 KING       PRESIDENT            17-11月-81                                   10
      7934 MILLER     CLERK           7782 23-1月 -82                                   10
      7566 JONES      MANAGER         7839 02-4月 -81                                   20
      7902 FORD       ANALYST         7566 03-12月-81                                   20
      7876 ADAMS      CLERK           7788 23-5月 -87                                   20
      7369 SMITH      CLERK           7902 17-12月-80                                   20
      7788 SCOTT      ANALYST         7566 19-4月 -87                                   20
      7521 WARD       SALESMAN        7698 22-2月 -81           1250        500         30
      7844 TURNER     SALESMAN        7698 08-9月 -81           1500          0         30
      7499 ALLEN      SALESMAN        7698 20-2月 -81           1600        300         30

     EMPNO ENAME      JOB              MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------------- ---------- ---------- ----------
      7900 JAMES      CLERK           7698 03-12月-81            950                    30
      7698 BLAKE      MANAGER         7839 01-5月 -81           2850                    30
      7654 MARTIN     SALESMAN        7698 28-9月 -81           1250       1400         30

已选择14行。

你可能感兴趣的:(oracle,安全,访问控制,VPD)