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:
As Figure 25-1 shows, Java EE applications running on Oracle WebLogic Server can integrate with and leverage the audit framework seamlessly:
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.
Take these steps to integrate your application with the audit framework:
Create an audit definition file, component_events.xml
.
Package the component_events.xml
file and component_events_xlf.jar
in the application EAR
file.
Add the audit event API to the application code to enable it to log audit events.
Integrate with a reporting tool such as Oracle Business Intelligence Publisher for reporting.
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.This task involves creating the following files:
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.
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.
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 becomponent_events.xml
and component_events_xlf.jar
respectively.This section explains the various mechanisms by which applications can register with the audit service:
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.
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>
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; } });
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.
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(); } } }
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; } });
Applications can programmatically access the run-time audit service to generate their own audit events using the client API.
The audit client API is as follows:
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.
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. |
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); }
As the application's audit requirements evolve, you can update the integration to reflect the changes. The steps are as follows:
Update the audit definition file. Be mindful of the versioning rules as you take this step.
See Also:
Section 13.5.3.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.
Verify your changes.