Skip Headers
Oracle® Database Real Application Security Administrator's and Developer's Guide
12c Release 1 (12.1)

E10479-19
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Master Index
Master Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

11 Real Application Security HR Demo

This chapter describes the following topics:

Overview of the Security HR Demo

This Human Resources (HR) Demonstration shows how to use basic Real Application Security (RAS) features. This tutorial is an end-to-end use case scenario. PL/SQL scripts, a Java program source file, and log files can be found in Appendix C.

The HR demo secures the HR.EMPLOYEE table by applying a data security policy that has three realms:

  1. An employee's own record realm. The ACL, EMP_ACL controls this realm, which grants application role EMP_ROLE privileges to access the realm, including the SALARY column.

  2. All the records in the IT department realm. The ACL, IT_ACL controls this realm, which grants application role IT_ROLE privileges to access the realm, but excluding the SALARY column.

  3. All the employee records realm. The ACL, HR_ACL controls this realm, which grants application role HR_ROLE privileges to access the realm, including the SALARY column.

The HR Demo defines two application users to demonstrate the effects of the policy:

  • DAUSTIN, an application user in the IT department. He has application roles EMP_ROLE and IT_ROLE. So, he can access realm #1 and realm #2 mentioned previously; that is, he can view employee records in the IT department, but he cannot view the SALARY column, except for his own salary record.

  • SMAVRIS, an application user in HR department. She has application roles EMP_ROLE and HR_ROLE. So, she can access realm #1 and realm #3 mentioned previously; that is, she can view and update all the employee records.

The HR Demo scripts show:

  • How to create Real Application Security objects: application user, application role, ACL, security class, and data security policy.

  • How to use the data security policy to secure rows (using realm constraints) and columns (using a column constraint) of a table.

  • How to directly logon to a database with application users (requiring a password), and how to create, attach, detach, and destroy a Real Application Security session.

  • How to enable and disable an application role in a Real Application Security session.

What Each Script Does

The Security HR demo use case runs the following set of PL/SQL scripts to set up components and run the demo:

  • hrdemo_setup.sql: sets up the demo components by:

    • Creating a database user as the Real Application Security Administrator and then connecting as the Real Application Security Administrator to create the components.

    • Creating a database role, DB_EMP.

    • Creating an IT application user, DAUSTIN.

    • Creating an HR application user, SMAVRIS.

    • Creating application roles: EMP_ROLE, IT_ROLE, and HR_ROLE, and then granting the database role DB_EMP to each of these application roles.

    • Granting application roles EMP_ROLE and IT_ROLE to application user DAUSTIN.

    • Granting application roles EMP_ROLE and HR_ROLE to application user SMAVRIS.

    • Creating the VIEW_SALARY privilege and creating the HRPRIVS security class in which to scope the privilege.

    • Creating three ACLs: EMP_ACL, IT_ACL, and HR_ACL, in which:

      • EMP_ACL grants the EMP_ROLE the SELECT database privilege and VIEW_SALARY application privilege to view an employee's own record, including the SALARY column.

      • IT_ACL grants the IT_ROLE only the SELECT database privilege to view the employee records in the IT department, but it does not grant the VIEW_SALARY privilege that is required for access to the SALARY column.

      • HR_ACL grants the HR_ROLE ALL privileges, which means all the privileges in the ACL's security class. In this case, ALL privileges includes SELECT, INSERT, UPDATE, and DELETE database privileges to view and update all employee's records, and granting the VIEW_SALARY application privilege to view the SALARY column.

    • The HR demo secures the HR.EMPLOYEE table by creating and applying the data security policy, EMPLOYEES_DS, that has the following three realms and column constraint:

      • An employee's own record realm. The ACL, EMP_ACL controls this realm, which grants application role EMP_ROLE privileges to access the realm, including the SALARY column.

      • All the records in the IT department realm. The ACL, IT_ACL controls this realm, which grants application role IT_ROLE privileges to access the realm, but excluding the SALARY column.

      • All the employee records realm. The ACL, HR_ACL controls this realm, which grants application role HR_ROLE privileges to access the realm, including the SALARY column.

      • A column constraint that protects the SALARY column by requiring the VIEW_SALARY privilege to view its sensitive data.

    • Validating all the objects that have been created to ensure that all configurations are correct.

    • Setting up the mid-tier related configuration by creating a DISPATCHER user, setting the password for this user, and granting the administrative roles, xscacheadmin and xssessionadmin to this DISPATCHER user.

  • hrdemo_run.sql: runs the demo with direct logon, demonstrating:

    • That the IT application user, DAUSTIN, can view the records in the IT department, but can only view his own salary record, and cannot update his own record.

    • That the HR application user, SMAVRIS, can view all the records, including all salary rows in the SALARY column, and can update any record.

  • hrdemo_run_sess.sql: runs the demo creating and attaching to a Real Application Security session, demonstrating:

    • Connecting as the Real Application Security Administrator and creating an application session for application user SMAVRIS and attaching to it.

    • Displaying the current user as SMAVRIS.

    • Displaying the enabled database roles as DB_EMP and application roles as EMP_ROLE, HR_ROLE, and XSPUBLIC for the current user SMAVRIS.

    • That SMAVRIS application user can view all records including all salary rows in the SALARY column.

    • Disabling the HR_ROLE and thus limiting application user SMAVRIS to viewing only her own employee record.

    • Enabling the HR_ROLE, thus allowing SMAVRIS application user to view all records, including all salary rows in the SALARY column again.

    • Detaching from the application session.

    • Destroying the application session.

  • hrdemo_clean.sql: performs a cleanup operation that removes: application roles, application users, ACLs, the data security policy, the database role, the Real Application Security administrative user, and the mid-tier dispatcher user.

  • HRDemo.java: runs the HR Demo using the Java interface.

"Setting Up the Security HR Demo Components" describes in more detail how each of the Real Application Security components is created along with performing some other important tasks.

Setting Up the Security HR Demo Components

Before you can create Real Application Security components, you must first create a database user as the Real Application Security Administrator, grant this administrator dba and xs_session_admin privileges, and then connect to the database as the Real Application Security Administrator.

connect sys/password as sysdba
grant dba, xs_session_admin to rasadm identified by rasadm;
connect rasadm/rasadm;

Create Roles and Application Users

Create the database role DB_EMP and grant this role the necessary table privileges. This role is used to grant the required object privileges to application users.

create role db_emp;
grant select, insert, update, delete on hr.employees to db_emp; 

Create the application role EMP_ROLE for common employees.

exec xs_principal.create_role(name => 'emp_role', enabled => true);

Create an application role IT_ROLE for the IT department.

exec xs_principal.create_role(name => 'it_role', enabled => true);

Create an application role HR_ROLE for the HR department.

exec xs_principal.create_role(name => 'hr_role', enabled => true);

Grant the DB_EMP database role to the three application roles, so they each have the required object privilege to access the table.

grant db_emp to emp_role;
grant db_emp to it_role;
grant db_emp to hr_role;

Create the application users.

Create application user DAUSTIN (in the IT department) and grant this user application roles EMP_ROLE and IT_ROLE.

exec  xs_principal.create_user(name => 'daustin', schema => 'hr');
exec  sys.xs_principal.set_password('daustin', 'welcome1');
exec  xs_principal.grant_roles('daustin', 'emp_role');
exec  xs_principal.grant_roles('daustin', 'it_role');

Create application user SMAVRIS (in the HR department) and grant this user application roles EMP_ROLE and HR_ROLE.

exec  xs_principal.create_user(name => 'smavris', schema => 'hr');
exec  sys.xs_principal.set_password('smavris', 'welcome1');
exec  xs_principal.grant_roles('smavris', 'emp_role');
exec  xs_principal.grant_roles('smavris', 'hr_role');

Create the Security Class and ACLs

Create a security class HRPRIVS based on the predefined DML security class. HRPRIVS has a new privilege VIEW_SALARY, which controls access to the SALARY column.

declare
begin
  xs_security_class.create_security_class(
    name        => 'hrprivs', 
    parent_list => xs$name_list('sys.dml'),
    priv_list   => xs$privilege_list(xs$privilege('view_salary')));
end;
/

Create three ACLs, EMP_ACL, IT_ACL, and HR_ACL to grant privileges for the data security policy to be defined later.

declare  
  aces xs$ace_list := xs$ace_list();  
begin 
  aces.extend(1);
 
  -- EMP_ACL: This ACL grants EMP_ROLE the privileges to view an employee's
  --          own record including SALARY column.
  aces(1) := xs$ace_type(privilege_list => xs$name_list('select','view_salary'),
                         principal_name => 'emp_role');
 
  xs_acl.create_acl(name      => 'emp_acl',
                    ace_list  => aces,
                    sec_class => 'hrprivs');
  
  -- IT_ACL:  This ACL grants IT_ROLE the privilege to view the employee
  --          records in IT department, but it does not grant the VIEW_SALARY
  --          privilege that is required for access to SALARY column.
  aces(1) := xs$ace_type(privilege_list => xs$name_list('select'),
                         principal_name => 'it_role');
 
  xs_acl.create_acl(name      => 'it_acl',
                    ace_list  => aces,
                    sec_class => 'hrprivs');
 
  -- HR_ACL:  This ACL grants HR_ROLE the privileges to view and update all
  --          employees' records including SALARY column.
  aces(1):= xs$ace_type(privilege_list => xs$name_list('select', 'insert', 
                                          'update', 'delete', 'view_salary'),
                        principal_name => 'hr_role');
 
  xs_acl.create_acl(name      => 'hr_acl',
                    ace_list  => aces,
                    sec_class => 'hrprivs');
end;
/

Create the Data Security Policy

Create data security policy for the EMPLOYEE table. The policy defines three realm constraints and a column constraint that protects the SALARY column.

declare
  realms   xs$realm_constraint_list := xs$realm_constraint_list();      
  cols     xs$column_constraint_list := xs$column_constraint_list();
begin  
  realms.extend(3);
 
  -- Realm #1: Only the employee's own record. 
  --           EMP_ROLE can view the realm including SALARY column.     
  realms(1) := xs$realm_constraint_type(
    realm    => 'email = xs_sys_context(''xs$session'',''username'')',
    acl_list => xs$name_list('emp_acl'));
 
  -- Realm #2: The records in the IT department.
  --           IT_ROLE can view the realm excluding SALARY column.
  realms(2) := xs$realm_constraint_type(
    realm    => 'department_id = 60',
    acl_list => xs$name_list('it_acl'));
 
  -- Realm #3: All the records.
  --           HR_ROLE can view and update the realm including SALARY column.
  realms(3) := xs$realm_constraint_type(
    realm    => '1 = 1',
    acl_list => xs$name_list('hr_acl'));
 
  -- Column constraint protects SALARY column by requiring VIEW_SALARY 
  -- privilege.
  cols.extend(1);
  cols(1) := xs$column_constraint_type(
    column_list => xs$list('salary'),
    privilege   => 'view_salary');
 
  xs_data_security.create_policy(
    name                   => 'employees_ds',
    realm_constraint_list  => realms,
    column_constraint_list => cols);
end;
/

Apply the data security policy to the EMPLOYEES table.

begin
  xs_data_security.apply_object_policy(
    policy => 'employees_ds', 
    schema => 'hr',
    object =>'employees');
end;
/

Validate the Real Application Security Objects

After you create these Real Application Security objects, validate them to ensure they are all properly configured.

begin
  if (xs_diag.validate_workspace()) then
    dbms_output.put_line('All configurations are correct.');
  else
    dbms_output.put_line('Some configurations are incorrect.');
  end if;
end;
/
-- XS$VALIDATION_TABLE contains validation errors if any.
-- Expect no rows selected.
select * from xs$validation_table order by 1, 2, 3, 4;

Set up the Mid-Tier Related Configuration

Set up the mid-tier configuration to be used later. This involves creating a DISPATCHER user and password and granting this user the xscacfeadmin and xsessionadmin Real Application Security administrator privileges.

exec xs_principal.create_user(name=>'dispatcher', schema=>'HR');
exec sys.xs_principal.set_password('dispatcher', 'welcome1');
 
exec xs_principal.grant_roles('dispatcher', 'xscacheadmin');
exec xs_principal.grant_roles('dispatcher', 'xssessionadmin');

Running the Security HR Demo Using Direct Logon

To run the HR Demo, first connect as application user DAUSTIN, who has only the EMP_ROLE and IT_ROLE application roles.

conn daustin/welcome1;

Customize how secured column values are to be displayed in SQL*Plus using the default indicator asterisks (*******) in place of column values.

SET SECUREDCOL ON UNAUTH *******

Perform a query to show that application user DAUSTIN can view the records in the IT department, but can only view his own SALARY column.

select email, first_name, last_name, department_id, manager_id, salary 
from employees order by email;

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees order by email;
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
AHUNOLD    Alexander       Hunold                     60        102 *******
BERNST     Bruce           Ernst                      60        103 *******
DAUSTIN    David           Austin                     60        103    4800
DLORENTZ   Diana           Lorentz                    60        103 *******
VPATABAL   Valli           Pataballa                  60        103 *******
 
5 rows selected.

Set to the default display for how secured column values are to be displayed in SQL*Plus by displaying null values in place of column values for application users without authorization, and in place of column values where the security level is unknown.

SET SECUREDCOL OFF 

Perform an update operation to show that application user is not authorized to update the record.

update employees set manager_id = 102 where email = 'DAUSTIN';

SQL> update employees set manager_id = 102 where email = 'DAUSTIN';
 
0 rows updated.

Perform a query to show that the record is unchanged.

select email, first_name, last_name, department_id, manager_id, salary
from employees where email = 'DAUSTIN';

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where email = 'DAUSTIN';
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
DAUSTIN    David           Austin                     60        103    4800
 
1 row selected.

Connect as application user SMAVRIS, who has both EMP_ROLE and HR_ROLE roles.

conn smavris/welcome1;

Perform a query to show that application user SMAVRIS can view all the records including SALARY column.

select email, first_name, last_name, department_id, manager_id, salary 
from employees where department_id = 60 or department_id = 40
order by department_id, email;

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where department_id = 60 or department_id = 40
  3  order by department_id, email;
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
SMAVRIS    Susan           Mavris                     40        101    6500
AHUNOLD    Alexander       Hunold                     60        102    9000
BERNST     Bruce           Ernst                      60        103    6000
DAUSTIN    David           Austin                     60        103    4800
DLORENTZ   Diana           Lorentz                    60        103    4200
VPATABAL   Valli           Pataballa                  60        103    4800
 
6 rows selected.

Perform a query to show that application user SMAVRIS can access all the records.

select count(*) from employees;

SQL> select count(*) from employees;
 
  COUNT(*)
----------
       107
 
1 row selected.

Perform an update of the record to show that application user SMAVRIS can update the record.

update employees set manager_id = 102 where email = 'DAUSTIN';

SQL> update employees set manager_id = 102 where email = 'DAUSTIN';
 
1 row updated.

Perform a query to show that the record is changed.

select email, first_name, last_name, department_id, manager_id, salary
from employees where email = 'DAUSTIN';

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where email = 'DAUSTIN';
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
DAUSTIN    David           Austin                     60        102    4800
 
1 row selected.

Update the record to change it back to its original state.

update employees set manager_id = 103 where email = 'DAUSTIN';

SQL> update employees set manager_id = 103 where email = 'DAUSTIN';
 
1 row updated.

Running the Security HR Demo Attached to a Real Application Security Session

To run the demo attached to a Real Application Security session, the Real Application Security administrator must first create the session for an application user and attach to it. In the process, create a variable to remember the session ID.

connect rasadm/rasadm;

var gsessionid varchar2(32);

declare
  sessionid raw(16);
begin
  dbms_xs_sessions.create_session('SMAVRIS', sessionid);
  :gsessionid := rawtohex(sessionid);
  dbms_xs_sessions.attach_session(sessionid, null);
end ;
/

Display the current user.

select xs_sys_context('xs$session','username') from dual;

SQL> select xs_sys_context('xs$session','username') from dual;
 
XS_SYS_CONTEXT('XS$SESSION','USERNAME')
--------------------------------------------------------------------------------
SMAVRIS
 
1 row selected.

Display the enabled database and application roles for the current application user.

select role_name from v$xs_session_roles union
select role from session_roles order by 1;

SQL> select role_name from v$xs_session_roles union
  2  select role from session_roles order by 1;
 
ROLE_NAME
--------------------------------------------------------------------------------
DB_EMP
EMP_ROLE
HR_ROLE
XSPUBLIC
 
4 rows selected.

Perform a query to show that application user SMAVRIS can view all the records including SALARY column.

select email, first_name, last_name, department_id, manager_id, salary 
from employees where department_id = 60 or department_id = 40
order by department_id, email;

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where department_id = 60 or department_id = 40
  3  order by department_id, email;
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
SMAVRIS    Susan           Mavris                     40        101    6500
AHUNOLD    Alexander       Hunold                     60        102    9000
BERNST     Bruce           Ernst                      60        103    6000
DAUSTIN    David           Austin                     60        103    4800
DLORENTZ   Diana           Lorentz                    60        103    4200
VPATABAL   Valli           Pataballa                  60        103    4800
 
6 rows selected.

Perform a query to show that application user SMAVRIS can access all the records.

select count(*) from employees;

SQL> select count(*) from employees;
 
  COUNT(*)
----------
       107
 
1 row selected.

Disable the HR_ROLE. This will limit application user SMAVRIS to only be able to see her own record.

exec dbms_xs_sessions.disable_role('hr_role');

Perform a query

select email, first_name, last_name, department_id, manager_id, salary 
from employees where department_id = 60 or department_id = 40
order by department_id, email;

SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where department_id = 60 or department_id = 40
  3  order by department_id, email;
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
SMAVRIS    Susan           Mavris                     40        101    6500
 
1 row selected.

Enable the HR_ROLE so application user can view all the records including SALARY column.

exec dbms_xs_sessions.enable_role('hr_role');

Perform a query to show that application user can view all the records including SALARY column.

select email, first_name, last_name, department_id, manager_id, salary 
from employees where department_id = 60 or department_id = 40
order by department_id, email;

SQL> -- SMAVRIS can view all the records again.
SQL> select email, first_name, last_name, department_id, manager_id, salary
  2  from employees where department_id = 60 or department_id = 40
  3  order by department_id, email;
 
EMAIL      FIRST_NAME      LAST_NAME       DEPARTMENT_ID MANAGER_ID  SALARY
---------- --------------- --------------- ------------- ---------- -------
SMAVRIS    Susan           Mavris                     40        101    6500
AHUNOLD    Alexander       Hunold                     60        102    9000
BERNST     Bruce           Ernst                      60        103    6000
DAUSTIN    David           Austin                     60        103    4800
DLORENTZ   Diana           Lorentz                    60        103    4200
VPATABAL   Valli           Pataballa                  60        103    4800
 
6 rows selected.

Perform a query to show that application user SMAVRIS can access all the records.

select count(*) from employees;

SQL> select count(*) from employees;
 
  COUNT(*)
----------
       107
 
1 row selected.

Detach and destroy the application session.

declare
  sessionid raw(16);
begin
  sessionid := hextoraw(:gsessionid);
  dbms_xs_sessions.detach_session;
  dbms_xs_sessions.destroy_session(sessionid);
end;
/

Running the Security HR Demo Cleanup Script

After running the HR demo, you can run the clean up script to remove all of the Real Application Security components.

To start, connect as the Real Application Security Administrator and then begin removing components.

connect rasadm/rasadm;

Remove the data security policy from the EMPLOYEES table.

begin
  xs_data_security.remove_object_policy(policy=>'employees_ds', 
                                        schema=>'hr', object=>'employees');
end;
/

Delete the application roles and application users.

exec xs_principal.delete_principal('emp_role', xs_admin_util.cascade_option);
exec xs_principal.delete_principal('hr_role', xs_admin_util.cascade_option);
exec xs_principal.delete_principal('it_role', xs_admin_util.cascade_option);
exec xs_principal.delete_principal('smavris', xs_admin_util.cascade_option);
exec xs_principal.delete_principal('daustin', xs_admin_util.cascade_option);

Delete the security class and the ACLs.

exec xs_security_class.delete_security_class('hrprivs', xs_admin_util.cascade_option);
exec xs_acl.delete_acl('emp_acl', xs_admin_util.cascade_option);
exec xs_acl.delete_acl('it_acl', xs_admin_util.cascade_option);
exec xs_acl.delete_acl('hr_acl', xs_admin_util.cascade_option);

Delete the data security policy.

exec xs_data_security.delete_policy('employees_ds', xs_admin_util.cascade_option);

Delete the database role.

drop role db_emp;

Delete the Real Application Security Administrator.

connect sys/knl_test7 as sysdba
drop user rasadm;

Delete the DISPATCHER user used by the mid-tier.

exec xs_principal.delete_principal('dispatcher', xs_admin_util.cascade_option);

Running the Security HR Demo in the Java Interface

See "Output" for a description of the two queries that are returned from running the Security HR Demo in the Java interface.