如何使用策略组来实现行级别的VPD

我们知道可以使用基于行的VPD来隐式修改用户发出的SQL语句,从而限制用户能够查看到的数据。
VPD常用的是策略,不过使用策略组能够实现更大的功能。

1、创建驱动上下文
SQL> connect hsj/oracle
Connected.
SQL> CREATE or replace CONTEXT app_driver USING hsj.apps_context;

Context created.

2、创建设置驱动上下文的包:
SQL> CREATE OR REPLACE PACKAGE hsj.apps_context
is
  PROCEDURE set_driver ( policy_group varchar2 );
end;
/
  2    3    4    5
Package created.

SQL> CREATE OR REPLACE PACKAGE BODY hsj.apps_context
is
  PROCEDURE set_driver ( policy_group varchar2 ) is
    BEGIN
      DBMS_SESSION.SET_CONTEXT('APP_DRIVER', 'ACTIVE_APP', policy_group );
    END;
END;
/
  2    3    4    5    6    7    8
Package body created.

3、设置驱动上下文相关属性:
SQL> begin
  2    begin
  3      dbms_rls.drop_policy_context(
  4        object_schema =>'OE',
  5        object_name => 'ORDERS' ,
  6        namespace => 'APP_DRIVER',
  7        attribute => 'ACTIVE_APP');
  8     exception when others then
  9        null;
 10     end;
 11     dbms_rls.add_policy_context(
 12        object_schema =>'OE',
 13        object_name => 'ORDERS' ,
 14        namespace => 'APP_DRIVER',
 15        attribute => 'ACTIVE_APP');
 16  end;
 17  /

PL/SQL procedure successfully completed.

4、创建oe_app上下文以及设置属性的包
SQL> CREATE or replace CONTEXT oe_app USING hsj.oe_context;

Context created.

SQL> CREATE OR REPLACE PACKAGE oe_context IS
  PROCEDURE set_cust_id;
  FUNCTION cust_order (
    object_schema       VARCHAR2,
    object_name VARCHAR2 )
    RETURN VARCHAR2;
END;
/  2    3    4    5    6    7    8

Package created.

SQL> CREATE OR REPLACE PACKAGE BODY oe_context IS
  2    PROCEDURE set_cust_id
  3    is
  4    BEGIN
  5      apps_context.set_driver('OE_GRP');     -- set the driver
  6    EXCEPTION
  7      WHEN no_data_found THEN
  8        apps_context.set_driver('XX');       -- set the driver
  9    END;
 10
 11    FUNCTION cust_order (
 12      object_schema  VARCHAR2,
 13      object_name    VARCHAR2 )
 14      RETURN VARCHAR2
 15    IS
 16    BEGIN
 17      RETURN 'customer_id = 102';
 18    END cust_order;
 19  END;
 20  /

Package body created.

5、创建ac_app上下文以及设置属性的包
SQL> CREATE or replace CONTEXT ac_app USING hsj.ac_context;

Context created.

SQL> CREATE OR REPLACE PACKAGE ac_context IS
  PROCEDURE set_cust_id;
  FUNCTION cust_order (
    object_schema       VARCHAR2,
    object_name VARCHAR2 )
    RETURN VARCHAR2;
END;
/  2    3    4    5    6    7    8

Package created.

SQL> CREATE OR REPLACE PACKAGE BODY ac_context IS
  2    PROCEDURE set_cust_id
  3    is
  4    BEGIN
  5      apps_context.set_driver('AC_GRP');     -- set the driver
  6    EXCEPTION
  7      WHEN no_data_found THEN
  8        apps_context.set_driver('XX');       -- set the driver
  9    END;
 10
 11    FUNCTION cust_order (
 12      object_schema  VARCHAR2,
 13      object_name    VARCHAR2 )
 14      RETURN VARCHAR2
 15    IS
 16    BEGIN
 17      RETURN 'customer_id = 101';
 18    END cust_order;
 19  END;
 20  /

Package body created.

6、创建策略组:
SQL> begin
  DBMS_RLS.CREATE_POLICY_GROUP('OE', 'ORDERS', 'OE_GRP');
end;
/
  2    3    4
PL/SQL procedure successfully completed.

SQL> begin
  DBMS_RLS.CREATE_POLICY_GROUP('OE', 'ORDERS', 'AC_GRP');
end;
/
  2    3    4
PL/SQL procedure successfully completed.

7、创建策略,并将该策略添加到策略组
SQL> begin
dbms_rls.add_grouped_policy (
 object_schema=>'oe',  object_name=>'orders',
 policy_group =>'oe_grp',
 policy_name => 'oe_security',
 function_schema =>'hsj',
 policy_function => 'oe_context.cust_order');
end;
/
  2    3    4    5    6    7    8    9
PL/SQL procedure successfully completed.

SQL> exec dbms_rls.add_grouped_policy ('oe', 'orders', 'ac_grp', 'ac_security','hsj', 'ac_context.cust_order');

PL/SQL procedure successfully completed.

8、赋予权限
SQL> connect hsj/oracle
Connected.
SQL> grant execute on ac_context to public;

Grant succeeded.

SQL> grant execute on oe_context to public;

Grant succeeded.

9、测试策略组是否生效。
SQL> connect oe/oe
Connected.
SQL> exec hsj.ac_context.set_cust_id;
SQL> select customer_id,order_total from orders;

CUSTOMER_ID ORDER_TOTAL
----------- -----------
        101     78279.6
        101     33893.6
        101       48552
        101     29669.9

SQL> exec hsj.oe_context.set_cust_id;

PL/SQL procedure successfully completed.

SQL> select customer_id,order_total from orders;

CUSTOMER_ID ORDER_TOTAL
----------- -----------
        102     42283.2
        102       10523
        102     10794.6
        102      5610.6

而事实上,oe.orders表里有105条记录:
SQL> connect / as sysdba
Connected.
SQL> select count(*) from oe.orders;

  COUNT(*)
----------
       105

因此很明显,我们设置的策略组生效了。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9842/viewspace-469871/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/9842/viewspace-469871/

VPD(Virtual Private Database)是一种安全机制,可以在数据库层面对用户进细粒度的数据访问控制。MySQL 5.5及以上版本引入了一个名为“database-level security”的概念,允许用户在数据库层面定义安全策略。以下是一个简单的演示: 1. 创建一个测试表格 ```sql CREATE TABLE test_table (id INT, name VARCHAR(20)); INSERT INTO test_table VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'); ``` 2. 创建一个包含安全策略的函数 ```sql DELIMITER // CREATE FUNCTION test_security_policy (schema_name VARCHAR(64), table_name VARCHAR(64)) RETURNS VARCHAR(1024) DETERMINISTIC BEGIN DECLARE security_filter VARCHAR(1024); SET security_filter = CONCAT('id <= 2'); RETURN security_filter; END; // DELIMITER ; ``` 此函数将返回一个字符串,其中包含用于限制用户对表格的访问的 SQL 语句。 3. 启用安全策略 ```sql GRANT SELECT ON test_table TO test_user@localhost; SET GLOBAL mysql.security_record_policy = 'test_security_policy'; ``` 此命令将允许 test_user 用户访问 test_table 表格,并启用上一步创建的安全策略函数。 4. 测试 ```sql SELECT * FROM test_table; -- 只返回id=1和id=2的 ``` 注意,由于安全策略将限制返回的数,因此仅返回 id=1 和 id=2 的。 以上就是 MySQL 实现 VPD 的简单演示。实际上,安全策略函数可以更复杂,可以根据当前用户的角色、访问时间、IP 地址等信息来限制访问。同时,MySQL 还提供了许多安全机制,如 SSL/TLS 加密、访问控制、身份验证等,可以在数据库层面确保数据的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值