25 Developing with the Audit Service

This chapter explains how applications can use the Oracle Fusion Middleware Audit Framework to provide auditing capabilities.

Oracle Fusion Middleware Audit Framework contains 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 (also known as audit clients) can:

  • create event definitions without the use of custom tables

  • register with the audit service when you deploy the application

  • change event definitions when redeploying the application

  • change audit configuration settings at run-time

This chapter contains these topics:

25.1 Application Integration with Audit Flow

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

Figure 25-1 Integrating Applications with the Audit Framework

Surrounding text describes Figure 25-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 13.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.

25.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:

See Also:

Chapter 7 which describes an alternate, template mode of processing audit artifacts.

25.3 Create Audit Definition Files

This task involves creating the following 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 13.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 13.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 13.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.

25.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:

25.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 13.5.3.1 for details.

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

25.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.

Table 25-1 shows the parameters with their options:

Table 25-1 Parameters for Audit Registration Service

Parameter Option Description

opss.audit.registration

OVERWRITE

Register component audit definition whether or not it is registered.

 

UPGRADE (default option)

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>

25.4.3 Programmatic Registration

You can register your application to the 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 25.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;
            }
        });

25.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.

25.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();
 
            }
        }
    }

25.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;
        }
    });

25.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.

25.6.1 Audit Client API

The audit client API is as follows:

See Also:

Section 25.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.

25.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.

25.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);
}

25.7 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 13.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.