28 Developing with the Audit Service

This chapter explains how applications (also known as audit clients) can use the Oracle Fusion Middleware Audit Framework to provide auditing capabilities. 11g Release 1 (11.1.1.6.0) introduces an audit service that enables you to integrate with the audit framework programmatically to log audit events and generate compliance reports using the same capabilities available to Oracle components.

Using the audit service, applications can:

This chapter contains these topics:

28.1 Application Integration with Audit Flow

As Figure 28-1 shows, Java EE applications running on Oracle WebLogic Server can integrate with and leverage the audit framework seamlessly:

Figure 28-1 Integrating Applications with the Audit Framework

Surrounding text describes Figure 28-1 .

During application deployment or audit service start-up, a client such as a Java EE application or Oracle component registers with the audit service. The registration service updates the metadata store with the latest audit definitions contained in component_events.xml and related files.

See Also:

Section 12.3 for details about the audit flow.

The rest of this chapter explains how you can integrate your applications with the audit flow to log audit events and create audit reports.

28.2 Integrating the Application with the Audit Framework

Take these steps to integrate your application with the audit framework:

  1. Create an audit definition file, component_events.xml.

  2. Package the component_events.xml file and component_events_xlf.jar in the application EAR file.

  3. Add the audit event API to the application code to enable it to log audit events.

  4. Integrate with a reporting tool such as Oracle Business Intelligence Publisher for reporting.

  5. Update the audit event definition and redeploy as needed.

The following sections provide more details on these tasks:

28.3 Create Audit Definition Files

This task involves creating the following files:

  • component_events.xml definition file

  • translation files

component_events.xml File

Create the audit definition component_events.xml file for your application.

For details about the composition of the component_events.xml file, and an example file, see Section 12.5.1.

When creating your audit definition file, you must be aware of certain rules that the registration service uses to create the audit metadata for the application. These include:

  • Version numbers. Any change to an audit event definition requires that the version ID be modified by changing the minor and/or major number.

    For more information about versioning, see Section 12.5.3.1.

  • Attribute mapping tables for unique mappings between your application's attribute definitions and database columns. Each custom attribute must have a mapping order number in its definition.

    For more information about attribute mapping, see Section 12.5.3.2.

Translation Files

Create the translation files required for your application.

Generate the files in XLIFF format and store them in component_events_xlf.jar; during registration, this information is stored in the audit metadata store along with the component audit event definition.

28.4 Register Application with the Registration Service

Java EE applications can be registered by packaging component_events.xml and component_events_xlf.jar in the META-INF folder of the application's EAR files. The audit registration service will process them automatically when the application is deployed.

Note:

The filenames must be component_events.xml and component_events_xlf.jar respectively.

This section explains the various mechanisms by which applications can register with the audit service:

28.4.1 Default Application Audit Registration

By default, the following registration activity occurs when you deploy, redeploy or undeploy the application:

  • Deployment - Registers the audit event definition to the audit metadata store if the application is not yet registered.

  • Redeployment - Upgrades the component audit event definition if the component is already registered. See Section 12.5.3.1 for details.

  • Undeployment - Removes the application's audit event definition from the audit metadata store.

28.4.2 Custom Application Audit Registration

Custom audit registration parameters are set in the WebLogic deployment descriptor weblogic-application.xml, which is also packaged in the META-INF folder of the application EAR files.

Note:

A different descriptor file is used by other application servers. See Oracle Fusion Middleware Third-Party Application Server Guide for details.

Table 28-1 shows the parameters with their options:

Table 28-1 Parameters for Audit Registration Service

Parameter Option Description

opss.audit.registration

OVERWRITE

Register component audit definition whether or not it is registered.

 

UPGRADE

Register component audit definition according to versioning support.

 

DISABLE

Do not register component audit definition.

opss.audit.deregistration

DELETE (default option)

Delete component audit definition from audit store when undeploying applications.

 

DISABLE

Keep component audit definition in audit store when undeploying applications.

opss.audit.componentType

 

Set the custom component type. (Optional)


Examples of weblogic-application.xml

The following sample from a weblogic-application.xml file demonstrates the use of registration and de-registration options:

<wls:application-param>
     <wls:param-name>opss.audit.registration</wls:param-name>
     <wls:param-value>DISABLE</wls:param-value>
</wls:application-param>
 
<wls:application-param>
     <wls:param-name>opss.audit.registration</wls:param-name>
     <wls:param-value>OVERWRITE</wls:param-value>
</wls:application-param>
 
<wls:application-param>
     <wls:param-name>opss.audit.unregistration</wls:param-name>
     <wls:param-value>DELETE</wls:param-value>
</wls:application-param>
 
<wls:application-param>
     <wls:param-name>opss.audit.unregistration</wls:param-name>
     <wls:param-value>DISABLE</wls:param-value>
</wls:application-param>

28.4.3 Programmatic Registration

You can register your application to audit service by invoking audit registration service programmatically. The registration logic is as follows:

AuditService auditService = JpsServiceLocator.getServiceLocator().lookup(AuditService.class);
AuditRegistration auditReg = <instance of AuditRegistration implementation>;
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
            public Object run() throws AuditException, IOException {
                auditService.register(auditReg);
                return null;
            }
        });

Invoking auditService.register requires that clients be granted AuditStoreAccessPermission with create, upgrade actions. For details about setting grants, see Section 28.6.2.

Here is an example of registering the audit service programmatically:

//
        JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
        JpsContext ctx = ctxFactory.getContext();
        //get audit service
        final AuditService auditService = ctx.getServiceInstance(AuditService.class);
 
        //create an audit registration instance
        final AuditRegistration auditReg = new SampleRegistration();
 
        //call audit service API to register audit event definition
        AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
            public Object run() throws AuditException, IOException {
                auditService.register(auditReg);
                return null;
            }
        });

28.5 Use the Administration Service APIs

The audit framework's Audit Administration Service (admin service) provides a set of APIs to query audit metadata and get/set audit runtime policy. The admin service is invoked as follows:

AuditService auditService = JpsContextFactory.getContextFactory().getContext().getServiceInstance(AuditService.class);
    AuditAdminService auditAdminService = auditService.getAdminService();

This section explains how to use the admin service APIs.

28.5.1 Query Audit Metadata

The APIs to query audit metadata are as follows:

Set<String> getComponentNames() throws AuditException;
 
    Map<String, ? extends AttributeGroup> getGenericAttributeGroups() throws AuditException;
   
    Collection<? extends EventCategory> getSystemEvents() throws AuditException;
 
    ComponentDefinition getComponentDef(String componentType) throws AuditException;
 
    AttributesDatabaseMap getAttributesMap(String componentType) throws AuditException;
   
    AttributesDatabaseMap getSystemAttributesMap() throws AuditException;

The following example demonstrates how to use the APIs to query audit metadata:

 //search events and attributes for a component
    Set<String> components = auditAdminService.getComponentNames();
    for (String componentType : components) {
        ComponentDefinition componentDef = auditAdminService.getComponentDef(componentType);
        //get attributes of a component
        AttributeGroup attrGroup = componentDef.getAttributes();
        for (AuditAttribute attr : attrGroup.getAttributes()) {
            AuditAttribute.DataType type = attr.getAttributeType();
            String attrName = attr.getName();
        }
 
        //get events of a component
        Collection<? extends EventCategory> events = componentDef.getEvents();
        for (EventCategory category : events) {
            if (category.isComponentSpecific()) { // isComponentSpecific() is true means the category is belong to a component, otherwise is system category
                Collection<? extends Event> categoryEvents = category.getAllEvents();
 
            }
        }
    }

28.5.2 View and Set Audit Run-time Policy

The APIs to retrieve and set audit runtime policy are as follows:

AuditPolicy getAuditPolicy(String componentType) throws AuditException;
   
    void setAuditPolicy(String componentType, AuditPolicy auditPolicy) throws AuditException;

The following example shows how to use the APIs to first obtain and then set the audit policy for a component:

 //get runtime policy for component JPS
    final String componentType = "JPS";
    AuditPolicy policy = auditAdminService.getAuditPolicy(componentType);
    String filterLevel = policy.getFilterLevel();
 
    //set runtim policy for component JPS
    final AuditPolicy newPolicy = new AuditPolicy("All", null, null);
    //setAuditPolicy() requires AuditStoreAccessPermission(<componentType>, "modify");
    AccessController.doPrivileged(new PrivilegedExceptionAction<Object>(){
        public Object run() throws AuditException {
            auditAdminService.setAuditPolicy(componentType, newPolicy);
            return null;
        }
    });

28.6 Add Application Code to Log Audit Events

Applications can programmatically access the run-time audit service to generate their own audit events using the client API.

28.6.1 Audit Client API

The audit client API is as follows:

See Also:

Section 28.6.2 for the prerequisite to using getAuditor.

Interface AuditService {
 
Auditor getAuditor(String componentType);
 
void register(AuditRegistration auditRegistration);
 
void unregister(AuditRegistration auditRegistration);
 
}
 
 
 
Interface Auditor {
 
boolean log(AuditEvent ev);
 
boolean isEnabled();

boolean isEnabled(String categoryName, String eventType, boolean eventStatus, Map<String, Object> properties);
 
}

public class oracle.security.jps.service.audit.AuditEvent {
   public AuditEvent(AuditContext ctx, String eventType, 
    String eventCategory, boolean eventStatus, String messageText);
   public void setApplicationName(String applicationName)   public void setAttribute(String attributeName, Object attributeValue)   public void setAttributeBoolean(String attributeName, boolean attributeValue)   public void setAttributeBoolean(String attributeName, Boolean attributeValue)   public void setAttributeBooleans(String attributeName, boolean[] values)   public void setAttributeByteArray(String attributeName, byte[] attributeValue)   public void setAttributeDate(String attributeName, Date attributeValue)   public void setAttributeDates(String attributeName, Date[] values)   public void setAttributeDouble(String attributeName, double attributeValue)   public void setAttributeDoubles(String attributeName, double[] values)   public void setAttributeFloat(String attributeName, float attributeValue)   public void setAttributeFloats(String attributeName, float[] values)   public void setAttributeInt(String attributeName, int attributeValue)   public void setAttributeInts(String attributeName, int[] values)   public void setAttributeLong(String attributeName, long attributeValue)   public void setAttributeLongs(String attributeName, long[] values)   public void setAttributeString(String attributeName, String attributeValue)   public void setAttributeStrings(String attributeName, String[] values)   public void setComponentName(String componentName)   public void setComponentType(String componentType)   public void setContextFields(String contextFields)   public void setECID(String ecid)   public void setEventCategory(String category)   public void setEventDefinition(Object eventDefinition)   public void setEventStatus(boolean status)   public void setEventTimestamp(long eventTimestamp)   public void setEventType(String eventType)   public void setFailureCode(String failureCode)   public void setHostId(String hostId)   public void setHostNetworkAddr(String hostNetworkAddr)   public void setInitiator(String initiator)   public void setInstanceId(String instanceId)   public void setMessageText(String messageText)   public void setModuleId(String moduleId)   public void setOracleHome(String oracleHome)   public void setOracleInstance(String oracleInstance)   public void setProcessId(String processId)   public void setRemoteIP(String value)              public void setResource(String value)             public void setRID(String rid)             public void setRoles(String value)            public void setTarget(String value)           public void setTargetComponentType(String targetComponentType)            public void setThreadId(String threadId)   public void setTransactionId(String transactionId)
}

Subsequent sections explain how to obtain permissions and a run-time auditor instance.

28.6.2 Set System Grants

Audit clients must have AuditStoreAccessPermission to invoke the Audit API. In this example, the grant allows application MyApp to call auditService.getAuditor("MyApp") in AccessController.doPrivileged block:

<grant>
  <grantee>
    <codesource>
      <url>file:${oracle.deployed.app.dir}/MyApp${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
 <permissions>
  <permission>
    <class>oracle.security.jps.service.audit.AuditStoreAccessPermission</class>
    <name>comp1</name>
    <actions>action1,action2,….</actions>
  </permission>
 </permissions>
</grant>

where the <actions> are a comma-separated list of authorized actions relating to the audit API that the audit client needs to invoke. The possible actions are as follows:

Action Authorizes client to

create

Call AuditService.register(AuditRegistration) to register a new audit component.

upgrade

Call AuditService.register(AuditRegistration) to upgrade an existing audit component event definition.

delete

Call AuditService.unregister(AuditRegistration) to de-register an audit component.

read

Call AuditService.getAuditor(String componentType) to get an instance of component auditor.

modify

Call AuditAdminService.setAuditPolicy(String componentType, AuditPolicy auditPolicy) to modify audit policy.


28.6.3 Obtain Auditor Instance

After your application registers to the audit service, it can get its runtime auditor instance programmatically from the OPSS audit service, as shown in the following sample code fragment:

//Gets audit service instance
 
final AuditService auditService = JpsServiceLocator.getServiceLocator().lookup(AuditService.class);
 
//Gets Auditor instance for application 'MyApp'
Auditor auditor = AccessController.doPrivileged(
                            new PrivilegedExceptionAction<Auditor>() {
                                public Auditor run() throws AuditException {
                                    return auditService.getAuditor("MyApp");
                                }
                            });
 
final String category = "Transaction";
final String eventName = "deposit";
 
//Check if event 'deposit' is enabled in filtering.
boolean enabled = auditor.isEnabled(category, eventName, "true", null);
if (enabled) {
        AuditContext ctx = new AuditContext();
        String message = "deposit transaction";
        //Creates an audit event
        AuditEvent ev = new AuditEvent(ctx, eventName, category, "true", message);
 
        //Sets event attributes
        ev.setInitiator("johnsmith");
        ev.setAttributeInt("accounting:AccountNumber", 2134567);
        ev.setAttributeDate("accounting:Date", new Date());
        ev.setAttributeFloat("accounting:Amount", 100.00);
 
        //Logs audit event
        boolean ret = auditor.log(event);
}

28.7 Generate Reports of Audit Data

The ultimate goal of audit integration is to create reports of audit events stored in audit database tables. As described in Section 13.6.1, audit events are saved into the common attribute table iau_common (Section 12.4.2.2), and the custom attribute tables iau_custom_nnn (Section 12.4.2.4). OPSS Common Audit Framework generates SQL scripts for components to create Oracle database views which component reporting applications can use to query audit event data from audit database tables.

The following steps (some of which you have already accomplished) are required:

  • Integrate with the audit framework using dynamic or declarative registration (Section 28.2 through Section 28.4).

  • Configure audit policies so that the run-time audit service logs events to generate audit data (Section 28.5 and Section 28.6).

  • Configure the audit loader to ensure bus-stop files are migrated to the database (Section 13.2).

  • Use the createAuditDBView command to generate a SQL script of audit definitions ("Viewing Audit Definitions for your Component" in Section 12.5.3.2).

  • Log in to the database as the IAU schema user to create a view using the SQL script from the previous step.

  • Configure your reporting application to query the view.

See Also:

Chapter 14, "Using Audit Analysis and Reporting"; Section 14.6.2 is specially useful for custom reporting.

Here is a sample output of createAuditDBView for component ApplicationAudit:

-- Audit View for Component
 
CREATE VIEW ApplicationAudit_AUDITVIEW AS
 
SELECT IAU_AUDITSERVICE.IAU_TRANSACTIONID AS AUDITSERVICE_TRANSACTIONID,
 
IAU_COMMON.IAU_COMPONENTTYPE AS ComponentType,
 
IAU_COMMON.IAU_MAJORVERSION AS MajorVersion,
 
IAU_COMMON.IAU_MINORVERSION AS MinorVersion,
 
IAU_COMMON.IAU_INSTANCEID AS InstanceId,
 
IAU_COMMON.IAU_HOSTID AS HostId,
 
IAU_COMMON.IAU_HOSTNWADDR AS HostNwaddr,
 
IAU_COMMON.IAU_MODULEID AS ModuleId,
 
IAU_COMMON.IAU_PROCESSID AS ProcessId,
 
IAU_COMMON.IAU_ORACLEHOME AS OracleHome,
 
IAU_COMMON.IAU_HOMEINSTANCE AS HomeInstance,
 
IAU_COMMON.IAU_ECID AS ECID,
 
IAU_COMMON.IAU_RID AS RID,
 
IAU_COMMON.IAU_CONTEXTFIELDS AS ContextFields,
 
IAU_COMMON.IAU_SESSIONID AS SessionId,
 
IAU_COMMON.IAU_TARGETCOMPONENTTYPE AS TargetComponentType,
 
IAU_COMMON.IAU_APPLICATIONNAME AS ApplicationName,
 
IAU_COMMON.IAU_EVENTTYPE AS EventType,
 
IAU_COMMON.IAU_EVENTCATEGORY AS EventCategory,
 
IAU_COMMON.IAU_EVENTSTATUS AS EventStatus,
 
IAU_COMMON.IAU_TSTZORIGINATING AS TstzOriginating,
 
IAU_COMMON.IAU_THREADID AS ThreadId,
 
IAU_COMMON.IAU_COMPONENTNAME AS ComponentName,
 
IAU_COMMON.IAU_INITIATOR AS Initiator,
 
IAU_COMMON.IAU_MESSAGETEXT AS MessageText,
 
IAU_COMMON.IAU_FAILURECODE AS FailureCode,
 
IAU_COMMON.IAU_REMOTEIP AS RemoteIP,
 
IAU_COMMON.IAU_TARGET AS Target,
 
IAU_COMMON.IAU_RESOURCE AS IAU_RESOURCE,
 
IAU_COMMON.IAU_ROLES AS Roles,
 
IAU_COMMON.IAU_DOMAINNAME AS DomainName,
 
IAU_COMMON.IAU_COMPONENTDATA AS ComponentData,
 
IAU_COMMON.IAU_AUDITUSER AS AuditUser,
 
IAU_COMMON.IAU_TENANTID AS TenantId,
 
IAU_COMMON.IAU_TRANSACTIONID AS TransactionId,
 
IAU_COMMON.IAU_USERTENANTID AS UserTenantId,
 
IAU_CUSTOM.IAU_INT_001 AS AccountNumber,
 
IAU_CUSTOM.IAU_DATETIME_001 AS Date,
 
IAU_CUSTOM.IAU_FLOAT_001 AS Amount,
 
IAU_CUSTOM.IAU_STRING_002 AS Status,
 
IAU_CUSTOM.IAU_FLOAT_002 AS Balance,
 
IAU_USERSESSION.IAU_AUTHENTICATIONMETHOD AS AuthenticationMethod
 
FROM IAU_AUDITSERVICE, IAU_COMMON, IAU_CUSTOM, IAU_USERSESSION WHERE IAU_COMMON.IAU_ID = IAU_AUDITSERVICE.IAU_ID AND IAU_COMMON.IAU_ID = IAU_CUSTOM.IAU_ID AND IAU_COMMON.IAU_ID = IAU_USERSESSION.IAU_ID AND IAU_COMMON.IAU_ComponentType = 'ApplicationAudit';

Using Oracle Business Intelligence Publisher

You can leverage Oracle Business Intelligence Publisher to generate reports from your application's audit data, utilizing the same reporting capabilities available to Oracle components.

The basic steps are as follows:

  1. Use a database view (created with the help of the createAuditDBView command) to generate an Oracle BI Publisher report template.

  2. Set up the Oracle BI Publisher report service.

  3. Copy the report template into Oracle BI Publisher to view component audit events.

  4. Generate reports with Oracle BI Publisher.

28.8 Update and Maintain Audit Definitions

As the application's audit requirements evolve, you can update the integration to reflect the changes. The steps are as follows:

  1. Update the audit definition file. Be mindful of the versioning rules as you take this step.

    See Also:

    Section 12.5.3.

  2. Redeploy the application EAR file with the updated event definition file. Alternatively, you can notify the audit registration service of the existence of a newer version.

  3. Verify your changes.