oracle FGAC(细粒度访问控制)介绍

在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、移除示例组件:

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

    CONNNECT SCOTT
    Enter password: password
    
    DROP TABLE orders_tab;
    DROP TABLE customers; 
    
  2. Connect as user SYS, connecting with AS SYSDBA.

    CONNECT sys/as sysdba
    Enter password: password
    
  3. Run the following statements to drop the components for this tutorial:

    DROP CONTEXT orders_ctx;
    DROP USER sysadmin_vpd CASCADE;
    DROP USER tbrooke;
    DROP USER owoods;

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

Dylan    Presents.

 
  
 
  
 
 

你可能感兴趣的:(PL/SQL开发)