Human Resources Demo Use Case: Implementation in Java

This section describes how an application session service supports user and roles managed externally by Oracle Fusion Middleware. This Java example is based on the Security Human Resources (HR) scenario. It uses the EMPLOYEES table in the sample HR schema.

See Also: For information about user and group to application roles mapping, see About the HR Demo Use Case - User Roles.

This example includes the following files and employee records that the three types of users can access:

Setting Up the HR Demo Application for External Principals (setup.sql)

Example: Set Up the HR Demo Application for External Principals shows a set up script (setup.sql) for setting up the HR Demo application for external principals.

This setup script performs the following operations:

Example: Set Up the HR Demo Application for External Principals

Rem Copyright (c) 2009, 2014, Oracle and/or its affiliates.
Rem All rights reserved.

SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

-- A PL/SQL function to determine manager-report relationship
conn hr/hr;

create or replace package hrutil as
 function ismyreport(id IN PLS_INTEGER)
 return PLS_INTEGER ;
end hrutil;
/

create or replace package body hrutil as
 function ismyreport(id IN PLS_INTEGER)
   return PLS_INTEGER is
   mycount PLS_INTEGER ;
   myid    PLS_INTEGER ;
 begin
   select employee_id into myid from hr.employees
   where UPPER(email) = XS_SYS_CONTEXT('PROFILE_NS','EMAIL');

   select count(employee_id) into mycount from hr.employees
   where employee_id = id start with manager_id = myid
   connect by prior employee_id = manager_id ;
   return mycount ;
 end ismyreport ;
end hrutil ;
/

-- Create a dynamic role for object privileges for external users.
connect sys/password as sysdba
show con_name;

-- Create a dynamic role for HR object privileges.
exec xs_principal.delete_principal('HROBJ',XS_ADMIN_UTIL.CASCADE_OPTION);
exec xs_principal.create_dynamic_role('HROBJ');

-- Create a db role to have HR object privileges.
drop role hr_db_obj;
create role hr_db_obj;
-- Grant object privilege to the db role.
grant select, insert, update, delete on hr.employees to hr_db_obj;

-- Grant db role to dynamic role.
grant hr_db_obj to HROBJ;


-- Create a security class with privilege view_sensitive_info, and
-- aggregate privilege update_info that implies data privileges,
-- update, delete, insert, which come from pre-defined security class
-- DML.
DECLARE
  priv_list  XS$PRIVILEGE_LIST;
BEGIN
  priv_list :=XS$PRIVILEGE_LIST(
     XS$PRIVILEGE(name=>'VIEW_SENSITIVE_INFO'),
     XS$PRIVILEGE(name=>'UPDATE_INFO',
                  implied_priv_list=>XS$NAME_LIST
                    ('"UPDATE"', '"DELETE"', '"INSERT"')));

  xs_security_class.create_security_class(
     name=>'HRPRIVS',
     parent_list=>XS$NAME_LIST('DML'),
     priv_list=>priv_list);
END;
/

-- External Principal (app role) Used for data security:
-- Such a principal must match the OPSS policy store.
-- roleName="HRREP" guid="37ED0D108C2F11E2BF802D569259982"
-- roleName="HRMGR" guid="4077A2B08C2F11E2BF802D569259982"
-- roleName="EMP"   guid="F917C3608CF011E2BF802D569259982"

-- Create an EMP Acl to grant EMP, HRMGR and HRREP privileges to access an employee record in the restricted departments.
DECLARE
  ace_list XS$ACE_LIST;
BEGIN
  ace_list := XS$ACE_LIST(
      XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('"SELECT"','VIEW_SENSITIVE_INFO'),
                  granted=>true,
                  principal_name=>'"37ED0D108C2F11E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL),
      XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('UPDATE_INFO'),
                  granted=>true,
                  principal_name=>'"4077A2B08C2F11E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL),
      XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('"SELECT"'),
                  granted=>true,
                  principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));

  xs_acl.create_acl(name=> 'EMP_ACL',
                   ace_list=> ace_list,
                   sec_class=>'HRPRIVS',
                   description=> 'Employee access to his/her data');
END;
/

-- Create a self Acl to grant EMP privileges to for an employee to see and update their own record.
-- Grant UPDATE, VIEW_SENSITIVE_INFO privileges to the EMP role.
DECLARE
 ace_list XS$ACE_LIST;
BEGIN
 ace_list := XS$ACE_LIST(
   XS$ACE_TYPE(privilege_list=> XS$NAME_LIST('"UPDATE"', 'VIEW_SENSITIVE_INFO'),
               principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));

 xs_acl.create_acl(name=> 'SELF_ACL',
                   ace_list=> ace_list,
                   sec_class=>'HRPRIVS',
                   description=> 'Employee access to his/her data');
END;
/

--   Create Manager ACL, to allow a manager to see their employee's salary.
--   Grant VIEW_SENSITIVE_INFO privileges to EMP role on the Manager's employees.
--
DECLARE
 ace_list XS$ACE_LIST;
BEGIN
 ace_list := XS$ACE_LIST(
   XS$ACE_TYPE(privilege_list=> XS$NAME_LIST('VIEW_SENSITIVE_INFO'),
               principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));

 xs_acl.create_acl(name=> 'MGR_ACL',
                   ace_list=> ace_list,
                   sec_class=>'HRPRIVS',
                   description=> 'Manager can see his reports salaray');
END;
/

-- Create data security policy for the EMPLOYEE table. The policy defines
-- an instant set to control the access to the employees in department
-- 60 and 100. It also defines an attribute constraint to control
-- the access to sensitive column SALARY.
DECLARE
  inst_sets XS$REALM_CONSTRAINT_LIST;
  attr_secs XS$COLUMN_CONSTRAINT_LIST;
BEGIN
  inst_sets :=
    XS$REALM_CONSTRAINT_LIST(
      XS$REALM_CONSTRAINT_TYPE(realm=> 'DEPARTMENT_ID in (60, 100)',
                           acl_list=> XS$NAME_LIST('EMP_ACL')));

  attr_secs :=
    XS$COLUMN_CONSTRAINT_LIST(
      XS$COLUMN_CONSTRAINT_TYPE(column_list=> XS$LIST('SALARY'),
                            privilege=> 'VIEW_SENSITIVE_INFO'));

  xs_data_security.create_policy(
          name=>'EMPLOYEES_DS',
          realm_constraint_list=>inst_sets,
          column_constraint_list=>attr_secs);
END;
/

-- Add more instance sets to the above data security.
declare
  inst1 xs$REALM_CONSTRAINT_TYPE;
  inst2 xs$REALM_CONSTRAINT_TYPE;
begin

  inst1 := xs$REALM_CONSTRAINT_TYPE(realm=> 'UPPER(email) = XS_SYS_CONTEXT(''PROFILE_NS'',''EMAIL'')',
                                acl_list=> XS$NAME_LIST('SELF_ACL'));

  xs_data_security.append_realm_constraints('EMPLOYEES_DS', inst1);


  inst2 := xs$REALM_CONSTRAINT_TYPE(realm=> 'hr.hrutil.ismyreport(employee_id) = 1',
                                acl_list=> XS$NAME_LIST('MGR_ACL'));

  xs_data_security.append_realm_constraints('EMPLOYEES_DS', inst2);
end;
/

-- Apply the data security policy on the table.

begin
  XS_DATA_SECURITY.apply_object_policy(schema=>'HR', object=>'EMPLOYEES',
                                       policy=>'EMPLOYEES_DS');
end;
/

-- Grant more privileges for the dispatcher.
exec XS_ADMIN_UTIL.GRANT_SYSTEM_PRIVILEGE('ADMIN_ANY_NAMESPACE','ts',XS_ADMIN_UTIL.PTYPE_XS);
grant select on  sys.dba_xs_session_roles to ts_role;

EXIT;

About the Application Session Filter Configuration File (web.xml)

Example: A Complete Application Session Filter Sample Configuration shows a complete application session filter sample configuration file (web.xml) that includes the filter, its parameters, and the listener. It references a filter for setting up the namespace (MyFilter.java) shown in Example: Filter to Set Up Application Namespace, and the sample servlet applications named MyHR.java shown in Example: Sample Servlet Application MyHR.java, in addition to: MySession.java, MyUpdate.java, and LogoutServlet.java, which are not shown.

MySession queries the V$XS_SESSION_ROLES view to show the roles in the application session, queries the users in XS$SESSION namespace to show the user in the application session, and queries the V$XS_SESSION_NS_ATTRIBUTES view to show the namespace in the application session, and then attaches to an application session.

MyUpdate performs an update on the HR.EMPLOYEES table to update the phone number for an employee.

LogoutServlet performs a logout operation, and then destroys the application session at the database.

In the ApplicationSessionFilter filter configuration, the filter section references the class ApllicationSessionFilter, describes a parameter application.datasource with a parameter value jdbc/myDBDS, and describes a parameter dynamic roles with a value of HROBJ that was created in the set up script in Example: Set Up the HR Demo Application for External Principals.

Example: A Complete Application Session Filter Sample Configuration

<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
    <filter>
        <filter-name>JpsFilter</filter-name>
        <filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
        <init-param>
            <param-name>enable.anonymous</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>remove.anonymous.role</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>application.name</param-name>
            <param-value>MyHRApp</param-value>
        </init-param>
        <!-- Following needed for Menu Security -->
        <!--init-param>
            <param-name>oracle.security.jps.jaas.mode</param-name>
            <param-value>subjectOnly</param-value>
        </init-param-->
    </filter>
    <filter>
        <filter-name>ApplicationSessionFilter</filter-name>
        <filter-class>oracle.security.xs.ee.session.ApplicationSessionFilter</filter-class>

        <init-param>
            <param-name>application.datasource</param-name>
            <param-value>jdbc/myDBDS</param-value>
        </init-param>
        <init-param>
            <param-name>dynamic.roles</param-name>
            <param-value>HROBJ</param-value>
        </init-param>
        <!--
         <init-param>
            <param-name>dispatcher.pool.max</param-name>
            <param-value>90</param-value>
        </init-param>
        -->
        <!-- init-param>
            <param-name>application.id</param-name>
            <param-value>MyHRApp</param-value>
        </init-param>
        <init-param>
            <param-name>session.provider</param-name>
            <param-value>XS</param-value>
        </init-param>
        <init-param>
            <param-name>db.url</param-name>
            <param-value>jdbc:oracle:thin:@myhost:1521:orcl</param-value>
        </init-param>

        <init-param>
            <param-name>dispatcher.id</param-name>
            <param-value>ts</param-value>
        </init-param>

        <init-param>
            <param-name>dispatcher.pwd.map</param-name>
            <param-value>XS_MAP</param-value>
        </init-param>
        <init-param>
            <param-name>dispatcher.pwd.key</param-name>
            <param-value>XS_KEY</param-value>
        </init-param>
        <init-param>
            <param-name>dispatcher.pool.min</param-name>
            <param-value>3</param-value>
        </init-param>
        <init-param>
            <param-name>dispatcher.pool.max</param-name>
            <param-value>10</param-value>
        </init-param -->

        <!--init-param>
            <param-name>namespaces</param-name>
            <param-value>sec_ns</param-value>
        </init-param-->
    </filter>
    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>trusted.MyFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>JpsFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>ApplicationSessionFilter</filter-name>
        <url-pattern>/myhr</url-pattern>
        <url-pattern>/mysession</url-pattern>
        <url-pattern>/myupdate</url-pattern>
        <url-pattern>/logout</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/myhr</url-pattern>
        <url-pattern>/mysession</url-pattern>
        <url-pattern>/myupdate</url-pattern>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
    </filter-mapping>
    <listener>
        <listener-class>oracle.security.xs.ee.session.ApplicationSessionListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>MySession</servlet-name>
        <servlet-class>app.MySession</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>LogoutServlet</servlet-name>
        <servlet-class>app.MyLogout</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyHR</servlet-name>
        <servlet-class>app.MyHR</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>MyUpdate</servlet-name>
        <servlet-class>app.MyUpdate</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MySession</servlet-name>
        <url-pattern>/mysession</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>LogoutServlet</servlet-name>
        <url-pattern>/logout</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MyHR</servlet-name>
        <url-pattern>/myhr</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>MyUpdate</servlet-name>
        <url-pattern>/myupdate</url-pattern>
    </servlet-mapping>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>my servlet</web-resource-name>
            <url-pattern>/myhr</url-pattern>
            <url-pattern>/mysession</url-pattern>
            <url-pattern>/myupdate</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>valid-users</role-name>
        </auth-constraint>
    </security-constraint>
    <login-config>
        <auth-method>CLIENT-CERT,FORM</auth-method>
        <form-login-config>
            <form-login-page>/login.jsp</form-login-page>
            <form-error-page>/error.jsp</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <role-name>valid-users</role-name>
    </security-role>
</web-app>

About the Sample Servlet Application (MyHR.java)

Example: Sample Servlet Application MyHR.java shows the sample servlet application named MyHR.java, which is referenced in the application session filter sample configuration (web.xml file) shown in Example: A Complete Application Session Filter Sample Configuration.

The MyHR application performs a query on the EMPLOYEES table and returns the results. If you have authorization, depending on your login credentials, you can perform certain tasks as described in:

From a check of the privilege on the ACLs (checkPrivilege), if you have UPDATE privilege, then you are authorized to perform an update of that employee’s record and the EMPLOYEE_ID will show a link that allows you access to that employee’s record.

Example: Sample Servlet Application MyHR.java

/* Copyright (c) 2009, 2014, Oracle and/or its affiliates.
All rights reserved.*/

package app;

import java.io.IOException;
import java.io.PrintWriter;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import java.util.ArrayList;
import java.util.Collection;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.sql.DataSource;

import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleResultSet.AuthorizationIndicator;
import oracle.security.xs.ee.session.ApplicationSessionException;
import oracle.security.xs.ee.session.ApplicationSessionService;

public class MyHR extends HttpServlet {
    private static final String CONTENT_TYPE = "text/html; charset=UTF-8";

    String query = " select emp.EMPLOYEE_ID, emp.first_name, emp.last_name, " +
                   "        emp.email, emp.phone_number, salary, emp.manager_id, " +
                   "        emp.department_id,ora_get_aclids(emp) as acl_id" +
                   " from hr.employees emp";

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void queryHR(PrintWriter out) throws ApplicationSessionException {

        DataSource dataSource = null;
        Connection conn = null;

        try {
            InitialContext ic;
            try {
                ic = new InitialContext();

                dataSource = (DataSource)ic.lookup("jdbc/myDBDS");

                if (dataSource != null)
                    try {
                        conn = dataSource.getConnection();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
            } catch (NamingException e) {
                e.printStackTrace();
            }

            try {
                queryHR(conn, out);
            } catch (Exception e) {
                e.printStackTrace();
            }

        } finally {

            if (conn != null)
                try {
                    conn.close();
                } catch (SQLException e) {
                }
        }

    }

    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException,
                                                           IOException {
        response.setContentType(CONTENT_TYPE);
        PrintWriter pw = response.getWriter();

        pw.println(HEADER);

        pw.println("<h1><font size=\"+2\">RAS Session Service Demo</font></h1>");
        pw.println("<font size=\"+1\">");
        pw.println("You are logged in as <b>" + request.getRemoteUser() + "</b>");

        try {
            queryHR(pw);
        } catch (ApplicationSessionException e) {
            e.printStackTrace();
        }

        pw.println(FOOTER);
        pw.close();
    }


    public Collection<Employee> queryHR(Connection conn ) {

      Statement stmt = null;
      ResultSet rs = null;

      Collection<Employee> result = new ArrayList<Employee>();

      try {
        // attach session
        ApplicationSessionService.attachSession(conn);

        stmt = conn.createStatement();
        rs = stmt.executeQuery(query);

        while (rs.next()) {
          Employee emp = new Employee();

          emp.setId(rs.getString("EMPLOYEE_ID"));

          AuthorizationIndicator ai =
                    ((OracleResultSet)rs).getAuthorizationIndicator("salary");

          if (ai == AuthorizationIndicator.NONE) {
            emp.setSalary(rs.getString("salary"));
          } else {
            emp.setSalary("******")  ;
          }

          // get ACL associated with the row
          emp.setAcl(rs.getBytes("acl_id"));
          // check "update" privilege
          boolean canUpdate = ApplicationSessionService.checkPrivilege(conn, emp.getAcl(), "UPDATE");

          emp.setUpdate(canUpdate);
          result.add(emp);

          emp.setFname(rs.getString("first_name"));
          emp.setLname(rs.getString("last_name"));
          emp.setEmail(rs.getString("email"));
          emp.setPhone(rs.getString("phone_number"));
          emp.setManagerId(rs.getString("manager_id"));
          emp.setDepId(rs.getString("department_id"));

        }
      } catch (ApplicationSessionException e) {
          e.printStackTrace();
          // process me
      } catch (SQLException e) {
          // process me
          e.printStackTrace();
      } finally {
         if (stmt != null) try {stmt.close();} catch (SQLException e) {};
         if (rs != null) try { rs.close();} catch (SQLException e)  {};
         try {ApplicationSessionService.detachSession(conn);} catch (ApplicationSessionException e) {};

      }

      return result;
    }

    public void queryHR(Connection conn, PrintWriter out ) {

        Collection<Employee> list = queryHR(conn);

        PrintWriter pw = out;

        pw.println("<br>Displaying employee record(s) that you can access.<br>");
        pw.println("</font>");
        pw.println("<i>NOTE: Salary is only shown if you are authorized to view,
 and ID is shown as a link if you are authorized to perform an update.</i><br>");

        out.println("<table border=\"1\">");

        String tmp;

        if (list.size() > 0) {
            out.println("<tr>");
            out.println("<th>ID</th>");
            out.println("<th>First Name</th>");
            out.println("<th>Last Name</th>");
            out.println("<th>Email</th>");
            out.println("<th>Phone</th>");
            out.println("<th>Salary</th>");

            out.println("<th>Department ID</th>");
            out.println("<th>Manager ID</th>");
            out.println("</tr>");
        }

        for (Employee e: list)  {

            if (e.canUpdate()) {
                tmp = "<a href=\"update.jsp?id=" + e.getId() + "\">" + e.getId() + "</a>";
            } else {
                tmp = e.getId();
            }

            out.println("<tr><td>" + tmp + "</td>");
            out.println("<td>" +  e.getFname() + "</td>");
            out.println("<td>" +  e.getLname() + "</td>");
            out.println("<td>" +  e.getEmail() + "</td>");
            out.println("<td>" +  e.getPhone() + "</td>");
            out.println("<td>" +  e.getSalary() + "</td>");
            out.println("<td>" +  e.getDepId() + "</td>");
            out.println("<td>" +  e.getManagerId() + "</td></tr>");

        }

        out.println("</TABLE>");

    };

    class Employee {

        String id;
        String salary;
        boolean update;
        String fname;
        String lname;
        String email;
        String phone;
        String managerId;
        String depId;
        byte[] acl;

        public void setId(String id) {
            this.id = id;
        }

        public String getId() {
            return id;
        }

        public void setSalary(String salary) {
            this.salary = salary;
        }

        public String getSalary() {
            return salary;
        }

        public void setUpdate(boolean canUpdate) {
            this.update = canUpdate;
        }

        public boolean canUpdate() {
            return update;
        }

        public void setFname(String fname) {
            this.fname = fname;
        }

        public String getFname() {
            return fname;
        }

        public void setLname(String lname) {
            this.lname = lname;
        }

        public String getLname() {
            return lname;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getEmail() {
            return email;
        }

        public void setPhone(String phone) {
            this.phone = phone;
        }

        public String getPhone() {
            return phone;
        }

        public void setManagerId(String managerId) {
            this.managerId = managerId;
        }

        public String getManagerId() {
            return managerId;
        }

        public void setDepId(String depId) {
            this.depId = depId;
        }

        public String getDepId() {
            return depId;
        }

        public void setAcl(byte[] acl) {
            this.acl = acl;
        }

        public byte[] getAcl() {
            return acl;
        }
    }

    private static String HEADER = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>"
            + "<meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\"/>"
            + "<title>Oracle</title>"
            + "<link href=\"css/general.css\" type=\"text/css\" rel=\"stylesheet\"/>"
            + "<link href=\"css/window.css\" type=\"text/css\" rel=\"stylesheet\"/>"
            + "<link href=\"css/login.css\" type=\"text/css\" rel=\"stylesheet\"/>"
            + "<script type=\"text/javascript\">"
            + "  if (top != self) top.location.href = location.href;"
            + "</script>"
            + "<style type=\"text/css\">"
            + "html { background-color: #001C34;}"
            + "</style>"
            + "</head>"
            + "<body onload=\"document.loginData.j_username.focus();\">"
            + "  <div id=\"top\">"
            + "   <div id=\"login-header\">"
            + "    <div id=\"login-logo\">"
            + "    <img  src=\"images/logo.png\"/>"
            + "</div>"
            + "  </div>"
            + "  <div id=\"content\">"
            + "<div id=\"app_data\"><div id=\"title\"></div>";

        private static String FOOTER = "<a href=\"/myapp/logout\">Logout</a>"
                + "</div></div><div id=\"info\"></div></div></body></html>";
}

About the Filter to Set Up the Application Namespace (MyFilter.java)

Example: Filter to Set Up Application Namespace shows a filter to set up the application namespace. This filter is named MyFilter.java, which is referenced in the application session filter sample configuration (web.xml file) shown in Example: A Complete Application Session Filter Sample Configuration.

This filter should be deployed as a separate jar, and SessionCodePermission should be granted to the jar file.

This filter first queries the V$XS_SESSION_ROLES view to show the roles in the Real Security Application session. Next, this filter demonstrates how trusted application code (a filter) firsts checks to see if a namespace exists (getNamespaceAttribute); then if not, it can set up a security critical namespace using session privilege elevation (attachSessionPrivileged) and namespace APIs (createNamespace, and setNamespaceAttribute) to create the namespace and set some namespace attributes.

Example: Filter to Set Up Application Namespace

/* Copyright (c) 2009, 2014, Oracle and/or its affiliates.
All rights reserved.*/

package trusted;


import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import oracle.security.xs.ee.session.ApplicationSessionException;
import oracle.security.xs.ee.session.ApplicationSessionService;
import oracle.security.xs.ee.session.NamespaceNotFoundException;


/**
 * Demonstrate how trusted application code (a filter) can set up
 * security critical namespace using session privilege elevation and
 * namespace APIs.
 *
 * The filter should be deployed as a separate jar, and SessionCodePermission
 * should be granted to the jar.
 */

public class MyFilter implements Filter {
    private FilterConfig _filterConfig = null;
    DataSource myDatasource = null;

    public void init(FilterConfig filterConfig) throws ServletException {
        _filterConfig = filterConfig;

    }

    public void destroy() {
        _filterConfig = null;
    }


    public void querySessionRoles(Connection conn) throws SQLException {

        String query =
            "select role_name from v$xs_session_roles order by role_name";
        String roles = null;

        try {

            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);

            System.out.println("<p> roles in RAS session (from myfilter):</p>");

            System.out.println("<TABLE>");

            while (rs.next()) {

                roles = rs.getString(1);
                System.out.println("<tr><td>" + roles + "</td></tr>");
            }
            System.out.println("</TABLE>");
        } finally {

        }

        return;
    }


    private boolean namespaceExists(String ns, String attribute, String value) throws ApplicationSessionException {


        try {
            return value.equalsIgnoreCase(ApplicationSessionService.getNamespaceAttribute(ns, attribute));
        } catch (NamespaceNotFoundException e) {
            return false;
        }
    }

    private Connection getConnection() {

        DataSource dataSource = null;
        InitialContext ic;
        try {
            ic = new InitialContext(); //TODO cache context

            dataSource = (DataSource)ic.lookup("jdbc/myDBDS");

            if (dataSource != null)
                try {
                    return dataSource.getConnection();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }


    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) {

        Connection conn = null;

        try {

            String email = ((HttpServletRequest)request).getRemoteUser();
            if ( email != null && !namespaceExists("PROFILE_NS", "EMAIL", email )) {



                conn = getConnection();

                //AccessController.doPrivileged(new AttachAction(conn), null);
                ApplicationSessionService.attachSessionPrivileged(conn, "SESSION_NS_DROLE");



                ApplicationSessionService.createNamespace(conn, "PROFILE_NS");
                ApplicationSessionService.setNamespaceAttribute(conn, "PROFILE_NS", "EMAIL", email);

                ApplicationSessionService.detachSession(conn);
            }

        } catch (ApplicationSessionException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (conn != null)
                try {
                    conn.close();
                } catch (SQLException e) {
                }
            }

        try {
            chain.doFilter(request, response);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        }
    }
}

About the HR Demo Use Case - User Roles

In the HR Demo Use Case, the Identity Management store contains the user name, user name’s password, and group name, while the OPSS security store contains the application roles and the user and group to application roles mapping. Example: User and Group to Application Roles Mapping shows a code snippet for the user and group to application roles mapping for one user LPOPP.

Example: User and Group to Application Roles Mapping

<app-role>
<name>EMP</name>
<display-name>Employee for dept #60 and dept #100</display-name>
<description>HR manager for dept #60 and representative for dept #100</description>
<guid>F917C3608CF011E2BF802D569259982</guid>
<class>oracle.security.jps.service.policystore.ApplicationRole</class>
<members>
    <member>
        <class>weblogic.security.principal.WLSUserImpl</class>
        <name>LPOPP</name>
    </member>
</members>
</app-role>

About the HR Demo (1) - Logged in as Employee LPOPP

Session Service HR Demo(1) Logged in as Employee LPOPP displays employee records that you can access logged in as an employee, LPOPP. You can see everyone’s record except their salary information, you can see your own salary information, and you can update your own contact information.

This access is set by:

Salary is only shown if you are authorized to view, and ID is shown as a link (Italic format in the table) if you are authorized to update.

Session Service HR Demo(1) Logged in as Employee LPOPP

ID First Name Last Name Email Phone Salary Department ID Manager ID
103 Alexander Hunold AHUNOLD 510.222.3388 ** 60 102
104 Bruce Ernst BERNST 590.423.4568 ** 60 103
105 David Austin DAUSTIN 590.423.4569 ** 60 103
106 Valli Pataballa VPATABAL 590.423.4560 ** 60 103
107 Diana Lorentz DLORENTZ 590.423.4567 ** 60 103
108 Nancy Greenberg NGREENBE 515.124.4569 ** 100 101
109 Daniel Faviet DFAVIET 515.124.4169 ** 100 108
110 John Chen JCHEN 515.124.4269 ** 100 108
111 Ismael Sciarra ISCIARRA 515.124.4369 ** 100 108
112 Jose Manuel Urman JMURMAN 515.124.4469 ** 100 108
113 Luis Popp LPOOP 133.444.5555 6900 100 108

About the HR Demo (2) - Logged in as HRMGR

Session Service HR Demo(2) Logged in as HR Manager HRMGR displays employee records that you can access logged in as an HR Manager, HRMGR. You can see every employee’s salary information, and you can update every employee’s contact information.

This access is set by the realm and grant: DEPARTMENT_ID in (60, 100), SELECT, UPDATE, and VIEW_SENSITIVE_INFO to HRMGR.

Salary is only shown if you are authorized to view, and ID is shown as a link (Italic format in the table) if you are authorized to update.

Session Service HR Demo(2) Logged in as HR Manager HRMGR

ID First Name Last Name Email Phone Salary Department ID Manager ID
103 Alexander Hunold AHUNOLD 510.222.3388 9000 60 102
104 Bruce Ernst BERNST 590.423.4568 6000 60 103
105 David Austin DAUSTIN 590.423.4569 4800 60 103
106 Valli Pataballa VPATABAL 590.423.4560 4800 60 103
107 Diana Lorentz DLORENTZ 590.423.4567 4200 60 103
108 Nancy Greenberg NGREENBE 515.124.4569 12008 100 101
109 Daniel Faviet DFAVIET 515.124.4169 9000 100 108
110 John Chen JCHEN 515.124.4269 8200 100 108
111 Ismael Sciarra ISCIARRA 515.124.4369 7700 100 108
112 Jose Manuel Urman JMURMAN 515.124.4469 7800 100 108
113 Luis Popp LPOOP 133.444.5555 6900 100 108

About the HR Demo (3) - Logged in as a Team Manager

Session Service HR Demo(3) Logged in as Team Manager AHUNOLD displays employee records that you can access logged in as a Team Manager, AHUNOLD. You can see your team member’s salary information; however, you cannot update their contact information, only your own contact information.

This access is set by the realm and grant: is my member(employee_id) =1 and VIEW_SENSITIVE_INFO to EMP.

Salary is only shown if you are authorized to view, and ID is shown as a link (Italic format in the table) if you are authorized to update.

Session Service HR Demo(3) Logged in as Team Manager AHUNOLD

ID First Name Last Name Email Phone Salary Department ID Manager ID
103 Alexander Hunold AHUNOLD 510.222.3388 9000 60 102
104 Bruce Ernst BERNST 590.423.4568 6000 60 103
105 David Austin DAUSTIN 590.423.4569 4800 60 103
106 Valli Pataballa VPATABAL 590.423.4560 4800 60 103
107 Diana Lorentz DLORENTZ 590.423.4567 4200 60 103
108 Nancy Greenberg NGREENBE 515.124.4569 ** 100 101
109 Daniel Faviet DFAVIET 515.124.4169 ** 100 108
110 John Chen JCHEN 515.124.4269 ** 100 108
111 Ismael Sciarra ISCIARRA 515.124.4369 ** 100 108
112 Jose Manuel Urman JMURMAN 515.124.4469 ** 100 108
113 Luis Popp LPOOP 133.444.5555 ** 100 108