oracleFGAC(细粒度访问控制)介绍(一)

2014-11-24 17:05:55 · 作者: · 浏览: 0

在ORACLE中,RLS有时也叫做虚拟私有数据库(VPD)或者细粒度访问控制(FGAC)。

RLS由8i引进,利用这一特性我们可以对表定义安全策略(并且指明对表的操作类型),实现对用户可以看到或者修改的数据进行限制。

这个功能大部分通过内置包DBMS_RLS实现。下面通过一个实例说明,详细情况请查阅官方文档:

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

环境:11.2.0.1.0 - 64bit

实现效果:SCOTT下新建一张客户表和订单表:CUSTOMERS、orders_tab,实现客户表内用户登录只能看到自己的订单;

1、创建用户账户和示例表:

dba用户登录:

GRANT CREATE SESSION, CREATE ANY CONTEXT, CREATE PROCEDURE, CREATE TRIGGER, ADMINISTER DATABASE TRIGGER TO sysadmin_vpd IDENTIFIED BY password;
GRANT EXECUTE ON DBMS_SESSION TO sysadmin_vpd;
GRANT EXECUTE ON DBMS_RLS TO sysadmin_vpd;
GRANT CREATE SESSION TO tbrooke IDENTIFIED BY password;
GRANT CREATE SESSION TO owoods IDENTIFIED BY password;
CONNECT scott
Enter password: password

CREATE TABLE customers (
 cust_no    NUMBER(4), 
 cust_name  VARCHAR2(20));

INSERT INTO customers VALUES (1234, 'TBROOKE');
INSERT INTO customers VALUES (5678, 'OWOODS');
GRANT SELECT ON customers TO sysadmin_vpd; 
CREATE TABLE orders_tab (
  cust_no  NUMBER(4),
  order_no NUMBER(4));

INSERT INTO orders_tab VALUES (1234, 9876);
INSERT INTO orders_tab VALUES (5678, 5432);
INSERT INTO orders_tab VALUES (5678, 4592);
GRANT SELECT ON orders_tab TO tbrooke;
GRANT SELECT ON orders_tab TO owoods;

2、创建基于会话的应用程序上下文:

CONNECT sysadmin_vpd
Enter password: password
CREATE OR REPLACE CONTEXT orders_ctx USING orders_ctx_pkg;
CREATE OR REPLACE PACKAGE orders_ctx_pkg IS 
  PROCEDURE set_custnum;
 END;
/
CREATE OR REPLACE PACKAGE BODY orders_ctx_pkg IS
  PROCEDURE set_custnum
  AS
    custnum NUMBER;
  BEGIN
     SELECT cust_no INTO custnum FROM scott.customers
        WHERE cust_name = SYS_CONTEXT('USERENV', 'SESSION_USER');
     DBMS_SESSION.SET_CONTEXT('orders_ctx', 'cust_no', custnum);
  EXCEPTION
   WHEN NO_DATA_FOUND THEN NULL;
  END set_custnum;
END;
/
3、创建登录触发器调用应用程序上下文包:
CREATE TRIGGER set_custno_ctx_trig AFTER LOGON ON DATABASE
 BEGIN
  sysadmin_vpd.orders_ctx_pkg.set_custnum;
 END;
/
4、创建策略函数(policy function):
CREATE OR REPLACE FUNCTION get_user_orders(
  schema_p   IN VARCHAR2,
  table_p    IN VARCHAR2)
 RETURN VARCHAR2
 AS
  orders_pred VARCHAR2 (400);
 BEGIN
  orders_pred := 'cust_no = SYS_CONTEXT(''orders_ctx'', ''cust_no'')'; 
 RETURN orders_pred;
END;
/
5、创建安全策略(security policy):
BEGIN
 DBMS_RLS.ADD_POLICY (
  object_schema    => 'scott', 
  object_name      => 'orders_tab', 
  policy_name      => 'orders_policy', 
  function_schema  => 'sysadmin_vpd',
  policy_function  => 'get_user_orders', 
  statement_types  => 'select');
END;
/
6、测试安全策略:
CONNECT tbrooke
Enter password: password
SELECT * FROM scott.orders_tab;

The following output should appear:

   CUST_NO    ORDER_NO
----------  ----------
      1234        9876
CONNECT owoods
Enter password: passwords

SELECT * FROM scott.orders_tab

The following output should appear:

   CUST_NO    ORDER_NO
----------  ----------
      5678        5432
      5678        4592

7、移除示例组件

Connect as user OE and remove the orders_tab and customers tables.

CONNNECT SCOTT
Enter password: password

DROP TABLE orders_tab;
DROP TABLE customers; 

Connect as user SYS, connecting with AS SYSDBA.

CONNECT sys/as sysdba
Enter password: password

Run the following statements to drop the components for this tutorial:

DROP CONTEXT