About Application Session APIs

All application session APIs are exposed through class ApplicationSessionService as static methods. The APIs operate on the current application session, which is set up based on the current Subject. Inside each API, an identity assertion is performed internally, to make sure the current application session matches the subject. If a mismatch is found, an ApplicationSesseionException exception is thrown. The caller code of the application session API should always be executed inside Subject.doAs, to be invoked as the subject. See the JDK’s Subject.doAs for more information.

This section describes the following topics:

About Application Session APIs

This section describes the following topics:

About Attaching to an Application Session

Attach the current user’s application session to the given database connection.

For application code to attach to the current user’s application session, no code based permission is needed. The application session works as is, no extra privilege is elevated through the attach.

Syntax

public static void attachSession(java.sql.Connection conn)
                          throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip

Example

See Example: Application Session APIs: AttachSession and DetachSession and Example: Namespace APIs.

Detaching from an Application Session

Detach the current user’s application session from the given database connection.

It is always a good practice to detach the application session at the application code’s final block. Not doing so may give an attached connection to some code that is not running under the correct user. It is caller’s responsibility to properly detach the application session once used.

If detach is not called, but attach is called again on the same connection, the server forces the detach from the previous attached application session, and attaches to the current application session.

Syntax

public static void detachSession(java.sql.Connection conn)
                          throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip

Example

Example: Application Session APIs: AttachSession and DetachSession shows sample code that uses the attach and detach API with a database query. The caller must decide the boundary of the attach and detach calls, based on the needs of the query.

Example: Application Session APIs: AttachSession and DetachSession

/**
  * Typical application code calling attach/detach for database query
  */
public void queryHR(Connection conn) {
      String query = " select emp.employee_id, emp.salary from hr.employees emp";
      Statement stmt = null;
      ResultSet rs = null;
      String id, salary;
      try {
        // attach connection to the current application session
        ApplicationSessionService.attachSession(conn);
        stmt = conn.createStatement();
        rs = stmt.executeQuery(query);
        while (rs.next()) {
          id = rs.getString("employee_id");
          salary = rs.getString("salary");
        }
      } catch (ApplicationSessionException e) {
      } catch (SQLException e) {
      } finally {
         // detach the current application session from the connection
         try { ApplicationSessionService.detachSession(conn); } catch (Exception e) {}
         if (stmt != null) try {stmt.close();} catch (SQLException e) {};
         if (rs != null) try { rs.close();} catch (SQLException e{};
      }
    }

Destroying an Application Session

Destroys the current application session at the database, and removes it from current thread’s execution context. This should be invoked by the application at logout. It destroys the current application session originally set up by the filter.

Syntax

public static void destroySession(java.sql.Connection conn)
                           throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip

Example

Example: Application Session APIs: DestroySession shows sample code that destroys the application session service.

Example: Application Session APIs: DestroySession

void doLogout(HttpServletRequest request) {

    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();
        }
        // invalidate Http session
        request.getSession().invalidate();
        // destroy XS session at DB
        ApplicationSessionService.destroySession(conn);

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

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

}

About the Privilege Elevation API

This section describes the following topic: Enabling a Dynamic Role in the Application Session.

Enabling a Dynamic Role in the Application Session

Attaches the current application session to a given database connection, and enables the Real Application Security dynamic role in the attached application session. This allows trusted application code to have higher privileges temporarily in order to perform some database operations, such as setting up application namespace.

This is for certain trusted application code to elevate the application session privilege. A Real Application Security dynamic role is enabled during attach. The trusted code is identified by java code permission.

Syntax

public static void attachSessionPrivileged(java.sql.Connection conn,
                                           java.lang.String role)
                                    throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
role The given dynamic role; must be request scope

Example

Each given dynamic role is associated with a code base permission as shown in Example: Privilege Elevation API (permission grant in jazn-data.xml)

See Example: Namespace APIs.

Usage Notes

The permission is always checked internally in the API, whether the java security manager is on or off. If the caller has the permission (that implies that the given role also matches the role defined in the policy file), the given dynamic role is enabled during attach; otherwise, the API fails with an AccessControlException.

The caller code (caller.jar file) and application session service code (xsee.jar) should both have the SessioncodePermission permission. This is sufficient when the caller.jar is invoked directly by the container. When caller.jar is invoked by another application code, it is up to the caller to decide whether the application code needs to have this permission. If the caller does not need the application to have this permission, the caller can invoke attachSessionPrivileged under AccessController.doPrivileged with a null AccessControllerContext. See the Java API for details. By doing this, the caller.jar fully trusts the application code.

Note that the dynamic role is only enabled on the attached application session, not the current application session. It is enabled within the window of attach and detach. The dynamic role must be defined as request scope at the database; otherwise, the following exception ORA-46055: invalid role specified is thrown.

Example: Privilege Elevation API

<grant>
            <grantee>
                <codesource>
                    <url>file:${domain.home}/servers/DefaultServer/tmp/_WL_user/MyWar/pi47ig/war/WEB-INF/lib/trusted.jar' </url>
                </codesource>
            </grantee>
            <permissions>
                <permission>
                    <class>oracle.security.xs.ee.session.SessionCodePermission</class>
                    <name> MY_NS_DROLE</name>
                    <actions>attach </actions>
                </permission>
            </permissions>
        </grant>
        <grant>
            <grantee>
                <codesource>
                    <url>file:${domain.home}/lib/xsee.jar</url>
                </codesource>
            </grantee>
            <permissions>
                <permission>
                    <class>oracle.security.xs.ee.session.SessionCodePermission</class>
                    <name>MY_NS_DROLE</name>
                    <actions>attac </actions>
                </permission>
            </permissions>
        </grant>

About Namespace APIs

This section describes the following topics:

About Creating a Namespace

Creates a namespace in the current application session. The namespace given must be predefined at the database, and the namespace ACL must allow the attached application session to perform a MODIFY_NAMESPACE operation, unless the ADMIN_ANY_NAMESPACE privilege is enabled in the application session.

Syntax

public static void createNamespace(java.sql.Connection conn,
                                   java.lang.String name)
                            throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
name The given namespace name

Example

See Example: Namespace APIs.

About Deleting a Namespace

Deletes a namespace from the current application session. The namespace given must be predefined at the database, and the namespace ACL must allow the attached application session to perform a MODIFY_NAMESPACE operation, unless the ADMIN_ANY_NAMESPACE privilege is enabled in the application session.

Syntax

public static void deleteNamespace(java.sql.Connection conn,
                                   java.lang.String name)
                            throws NamespaceNotFoundException,
                                   ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
name The given namespace name.

Example

See Example: Namespace APIs.

About Setting the Namespace Attribute

Sets the attribute value to the namespace in the current application session. The namespace given must be predefined at the database, and the namespace ACL must allow the attached application session to perform a MODIFY_ATTRIBUTE operation, unless the ADMIN_ANY_NAMESPACE privilege is enabled in the application session.

If the attribute does not exist on the namespace, the API creates the attribute with the given value; otherwise, it simply sets the existing value to the given value.

Syntax

public static void setNamespaceAttribute(java.sql.Connection conn,
                                         java.lang.String name,
                                         java.lang.String attribute,
                                         java.lang.String value)
                                  throws NamespaceNotFoundException,
                                         ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
name The given namespace name
attribute The given namespace attribute name
value The given namespace attribute value

Example

See Example: Namespace APIs.

About Deleting a Namespace Attribute

Deletes the attribute from the namespace in the current application session. The namespace given must be predefined at the database, and the namespace ACL must allow the attached application session to perform a MODIFY_ATTRIBUTE operation, unless the ADMIN_ANY_NAMESPACE privilege is enabled in the application session.

Syntax

public static void deleteNamespaceAttribute(java.sql.Connection conn,
                                            java.lang.String name,
                                            java.lang.String attribute)
                                     throws NamespaceNotFoundException,
                                            ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
name The given namespace name
attribute The given namespace attribute name

Example

See Example: Namespace APIs.

Getting a Namespace Attribute

Gets the attribute from the namespace in the current application session. The given namespace must be created. No database connection is needed and no privilege is checked for this operation.

The APIs that change namespace (other than getNamespaceAttribute) have a database connection as an input parameter. Those APIs update the namespace in the current application session in the JVM, as well as serialize the change to the database table. The connection must be attached. It uses the attached application session to determine whether the server can authorize the namespace change.

To allow only certain trusted application code to set up namespace. The connection can be attached with a dynamic role, which has elevated privileges (MODIFY_NAMESPACE, MODIFY_ATTRIBUTE) on the namespace. This is achieved using the attachSessionPrivileged API, and only granting the namespace privileges to the dynamic role.

Syntax

public static java.lang.String getNamespaceAttribute(java.lang.String name,
                                                     java.lang.String attribute)
                                              throws NamespaceNotFoundException,
                                                     ApplicationSessionException

Parameter

Parameter Description
name The given namespace name
attribute The given namespace attribute name

Example

Example: Namespace APIs shows a sample servlet filter that sets up namespace using namespace APIs and uses the application session privilege elevation API.

Important Points to Know About Using Application Namespace

The following usage information summarizes important points about using application namespace.

Example: Namespace APIs

/**
  * Trusted application code (servlet filter) sets up namespace
  * Using privilege elevation and namespace APIs
  */
public void doFilter(ServletRequest request, ServletResponse response,  FilterChain chain) throws IOException, ServletException {
   Connection conn = null;
   try {
     conn = myDatasource.getConnection();
     // Attach an application session with a dynamic role.
     ApplicationSessionService.attachSessionPrivileged(conn, "myNSRole");
     try {
       // Get the current value.
       String currentValue = ApplicationSessionService.getNamespaceAttribute("mySecuredNS", "myAttribute");
       // If the current value is not desired, set it.
       if  ("myValue".compareToIgnoreCase(currentValue) != 0)
          ApplicationSessionService.setNamespaceAttribute(conn, "mySecuredNS", "myAttribute", "myValue");
     } catch (NamespaceNotFoundException e) {
       // Namespace is not found, create it.
       ApplicationSessionService.createNamespace(conn, "mySecuredNS");
       // Set the attribute.
       ApplicationSessionService.setNamespaceAttribute(conn, "mySecuredNS", "myAttribute", "myValue");
     }
   } catch (SQLException e) {
   } catch (ApplicationSessionException e) {
   } finally {
     // Detach an application session.
     try { ApplicationSessionService.detachSession(conn); } catch (Exception e) {}
     if (conn != null) try { conn.close();} catch (Exception e) {}
   }
    // Execution of application code.
    chain.doFilter(request, response);

About the Check Privilege API

This section describes the following topic: Checking a Privilege on the ACLs.

Checking a Privilege on the ACLs

Checks the privilege on the ACLs using the attached application session of the given connection and includes these usage notes:

Syntax

public static boolean checkPrivilege(java.sql.Connection conn,
                                     byte[] acls,
                                     java.lang.String privilege)
                              throws ApplicationSessionException

Parameter

Parameter Description
conn The JDBC connection for database server roundtrip
acls The given ACL IDs in row format
privilege The given privilege name

Example

Example: CheckPrivilege API shows getting the ACL associated with the row and checking the UPDATE privilege on the ACL.

Example: CheckPrivilege API

    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;
    }