This demonstration is based on Oracle 10G Release 2.
From documentation:
Virtual private database (VPD) enables you to enforce security, to a fine level of granularity, directly on tables, views, or synonyms. Because security policies are attached directly to tables, views, or synonyms and automatically applied whenever a user accesses data, there is no way to bypass security.
When a user directly or indirectly accesses a table, view, or synonym protected with a VPD policy, the server dynamically modifies the SQL statement of the user. The modification creates a WHERE condition (known as a predicate) returned by a function implementing the security policy. The statement is modified dynamically, transparently to the user, using any condition that can be expressed in or returned by a function. VPD policies can be applied to SELECT, INSERT, UPDATE, INDEX, and DELETE statements.
Our VPD Requirement
So, there are four account manager under which, all the customers are assigned. Our requirement is to set a VPD, So that each account manager can
only see,modify his customers.
We assume each account manager will loginto the database using AM||account_mgr_id. That is, AM147, AM148, AM149 and AM145.
Steps for setting up a VPD.
******************************
Step 1: Set up a driving context. Connect database as OE.
--------
Step 2: Creating the package.
--------
---------
Step 4: Setting a ON LOGON trigger (from SYSDBA) to set the context for each loged in user.
Testing Of my VPD
Now, connecting AS new user AM145.
So, He can only view his customers only.
Now, customer_id=782 belongs to account manager 149. We will try to update it from AM145.
SQL> SELECT * FROM v$version; BANNER ---------------------------------------------------------------- Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod PL/SQL Release 10.2.0.1.0 - Production CORE 10.2.0.1.0 Production TNS for Linux: Version 10.2.0.1.0 - Production NLSRTL Version 10.2.0.1.0 - Production
From documentation:
Virtual private database (VPD) enables you to enforce security, to a fine level of granularity, directly on tables, views, or synonyms. Because security policies are attached directly to tables, views, or synonyms and automatically applied whenever a user accesses data, there is no way to bypass security.
When a user directly or indirectly accesses a table, view, or synonym protected with a VPD policy, the server dynamically modifies the SQL statement of the user. The modification creates a WHERE condition (known as a predicate) returned by a function implementing the security policy. The statement is modified dynamically, transparently to the user, using any condition that can be expressed in or returned by a function. VPD policies can be applied to SELECT, INSERT, UPDATE, INDEX, and DELETE statements.
Our VPD Requirement
QL> desc customers
Name Null? Type
----------------------------------------- -------- ----------------------------
CUSTOMER_ID NOT NULL NUMBER(6)
CUST_FIRST_NAME NOT NULL VARCHAR2(20)
CUST_LAST_NAME NOT NULL VARCHAR2(20)
CUST_ADDRESS CUST_ADDRESS_TYP
PHONE_NUMBERS PHONE_LIST_TYP
NLS_LANGUAGE VARCHAR2(3)
NLS_TERRITORY VARCHAR2(30)
CREDIT_LIMIT NUMBER(9,2)
CUST_EMAIL VARCHAR2(30)
ACCOUNT_MGR_ID NUMBER(6)
CUST_GEO_LOCATION MDSYS.SDO_GEOMETRY
DATE_OF_BIRTH DATE
MARITAL_STATUS VARCHAR2(20)
GENDER VARCHAR2(1)
INCOME_LEVEL VARCHAR2(20)
SQL> SELECT account_mgr_id,COUNT(customer_id)
2 FROM customers
3 GROUP BY account_mgr_id;
ACCOUNT_MGR_ID COUNT(CUSTOMER_ID)
-------------- ------------------
147 76
149 74
148 58
145 111
So, there are four account manager under which, all the customers are assigned. Our requirement is to set a VPD, So that each account manager can
only see,modify his customers.
We assume each account manager will loginto the database using AM||account_mgr_id. That is, AM147, AM148, AM149 and AM145.
Steps for setting up a VPD.
******************************
Step 1: Set up a driving context. Connect database as OE.
--------
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> CREATE OR REPLACE CONTEXT saubhik_cust_context USING cust_vpd_pkg; Context created. SQL>
Step 2: Creating the package.
--------
SQL> SHOW USER
USER is "OE"
SQL> CREATE OR REPLACE
PACKAGE cust_vpd_pkg
AS
--This procedure sets the application context.
--------------------------------------------
PROCEDURE set_app_context;
--This function builds the predicate (the where caluse).
--------------------------------------------------------
--This where caluse filters the rows and determines which can be accessed.
-----------------------------------------------------------------------
FUNCTION the_predicate(
pi_schema IN VARCHAR2,
pi_name IN VARCHAR2)
RETURN VARCHAR2;
END cust_vpd_pkg; 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 /
Package created.
SQL> CREATE OR REPLACE
PACKAGE BODY cust_vpd_pkg
AS
c_context_name VARCHAR2(30):= 'saubhik_cust_context';
c_attribute_name VARCHAR2(30):= 'ACCOUNT_MGR';
PROCEDURE set_app_context
IS
v_user_name VARCHAR2(30);
BEGIN
SELECT USER INTO v_user_name FROM dual;
DBMS_SESSION.SET_CONTEXT (namespace=>c_context_name, attribute=>c_attribute_name,value=>v_user_name);
END set_app_context;
FUNCTION the_predicate(
pi_schema IN VARCHAR2,
pi_name IN VARCHAR2)
RETURN VARCHAR2
IS
v_context_value VARCHAR2(200):=SYS_CONTEXT(c_context_name,c_attribute_name);
v_restriction VARCHAR2(2000);
BEGIN
IF v_context_value LIKE 'AM%' THEN
v_restriction:= ' ACCOUNT_MGR_ID = SUBSTR('''||v_context_value||''',3)';
ELSE
v_restriction:= NULL;
END IF;
RETURN v_restriction;
END THE_PREDICATE;
END cust_vpd_pkg; 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
29 /
Package body created.
SQL>
Step 3: Defining the policy using DBMS_RLS.---------
oracle@ubuntu-desktop:~$ sqlplus / as sysdba
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jul 4 17:17:27 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> BEGIN
DBMS_RLS.ADD_POLICY ( OBJECT_SCHEMA => 'OE'
,OBJECT_NAME => 'CUSTOMERS'
,POLICY_NAME => 'CUSTOMER_CREDIT_POLICY'
,FUNCTION_SCHEMA => 'OE'
,POLICY_FUNCTION => 'CUST_VPD_PKG.THE_PREDICATE'
,STATEMENT_TYPES =>'SELECT, UPDATE, DELETE'
,UPDATE_CHECK => FALSE
,ENABLE => TRUE
);
END; 2 3 4 5 6 7 8 9 10 11
12 /
PL/SQL procedure successfully completed.
SQL>
Step 4: Setting a ON LOGON trigger (from SYSDBA) to set the context for each loged in user.
oracle@ubuntu-desktop:~$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jul 4 17:20:24 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> CREATE OR REPLACE TRIGGER cust_vpd_trig AFTER LOGON ON DATABASE BEGIN OE.cust_vpd_pkg.set_app_context; END; 2 3 4 5 6 / Trigger created. SQL>
Testing Of my VPD
oracle@ubuntu-desktop:~$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jul 4 18:20:48 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> CREATE USER am145 identified by am145; User created. SQL> CREATE USER am147 identified by am147; User created. SQL> GRANT connect,resource to am145,am147; Grant succeeded. SQL> GRANT SELECT ON oe.customers to am145,am147; Grant succeeded. SQL>
Now, connecting AS new user AM145.
oracle@ubuntu-desktop:~$ sqlplus am145/am145
SQL*Plus: Release 10.2.0.1.0 - Production on Mon Jul 4 18:23:22 2011
Copyright (c) 1982, 2005, Oracle. All rights reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
SQL> SELECT customer_id,account_mgr_id FROM oe.customers;
CUSTOMER_ID ACCOUNT_MGR_ID
----------- --------------
101 145
102 145
103 145
104 145
105 145
106 145
107 145
108 145
109 145
110 145
111 145
...........................................
..........................................
So, He can only view his customers only.
Now, customer_id=782 belongs to account manager 149. We will try to update it from AM145.
SQL> l 1 UPDATE oe.CUSTOMERS SET cust_first_name='abc' 2* WHERE customer_id=782 SQL> / 0 rows updated. SQL>
No comments :
Post a Comment