Auditing (from V3.2r)

Document created by resplin Employee on Jun 6, 2015Last modified by alfresco-archivist on Aug 31, 2016
Version 2Show Document
  • View in full screen mode

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



Core Repository ServicesAuditing


Deprecation


This page was intended for use by internal developers.  Use Auditing (from V3.4) for more thorough examples and explanations.


Note Regarding WCM


Web Projects automatically capture a full version history of all changes to all assets, via the snapshot history, without requiring additional auditing functionality.  This doesn't prevent data from being captured in any part of WCM or DM, but assset metadata history is automatically available in WCM.


Introduction


A new auditing framework was introduced in version V3.2r (DOD5015 Records Management) to incorporate expanded requirements.  The new framework introduces new features such as:


  • Data is stored in inherently searchable (database-indexed) tables specific to the type of data.
  • Any type of data can be produced and passed to the AuditComponent (free-form, interceptor-driven, ad-hoc).
  • Audit configuration is used to filter, transform and generate data for eventual storage.
  • Callback-driven query API.

As of 3.2r:


  • Auditing is enabled and disabled using a global property:
  # Audit configuration
  audit.enabled=false

  • The new implementation is not (yet) the default:
  audit.useNewConfig=true

As of 3.3:


  • With the default product settings in v3.3, the new and old auditing implementations are enabled in tandem to allow backwards compatibility with settings in config/auditConfig.xml. To exclusively use the new implementation and configuration described here, set the following in alfresco-global.properties:
  audit.useNewConfig=true

Architecture


812px

Data Producers include any components that produce data that might be audited.  Data producers do not need to know anything about how the data will be stored.  In short, data is produced and thrown at the AuditComponent.recordAuditValues.  The only requirement is that each packet of data is a Map of data keyed by logical path names, which are specific to the producers.

Although the AuditService search should be used for data retrieval, for completeness, the following tables are used:


  • Tables exclusive to the new audit (AlfrescoPostCreate-3.2-AuditTables.sql)
    • alf_audit_model: Audit configuration files are recorded here.
    • alf_audit_application: An entry for each logical application.  There may be several audit applications defined in a single audit model.
    • alf_audit_entry: Each call to AuditComponent.recordAuditValues will result in an entry here.  There is a reference to a property.
  • Shared tables (AlfrescoPostCreate-3.2-PropertyValueTables.sql)
    • alf_prop_root: Entry point for properties: shared values are fully indexed; arbitrarily-deep collections; quick data query and reconstruction.
    • etc.



Example audit data passed to recordAuditValues():



Root path:
   /alfresco-api/post/NodeService/createStore
Map:
   args/protocol = 'workspace'
   args/identifier = 'SpacesStore'
   result = StoreRef[workspace://SpacesStore]

If the root path passes the initial filtration phase - there is at least one component interested in auditing the information - then the map is expanded.

Example expanded audit data:



Map:
   /alfresco-api/post/NodeService/createStore/args/protocol = 'workspace'
   /alfresco-api/post/NodeService/createStore/args/identifier = 'SpacesStore'
   /alfresco-api/post/NodeService/createStore/result = StoreRef[workspace://SpacesStore]

The filtered data is then passed through the path mappings, generating a new Map of data for each application.

Example path-mapped audit data:



Map:
   /MyApp/createStore = StoreRef[workspace://SpacesStore]

This data is then passed to any extractors and generators to produce a final Map of data that will be persisted.

Example persisted audit data:



Map:
   /MyApp/createStore/value = StoreRef[workspace://SpacesStore]
   /MyApp/createStore/rootNode = NodeRef[workspace://SpacesStore/fd123...]

Data Configuration


Location (v3.2r)


Audit configuration files (XSD at /alfresco/audit/alfresco-audit-3.2.xsd) are loaded into a registry using an instance of AuditModelReader:



    <bean id='auditModel.repository' class='org.alfresco.repo.audit.model.AuditModelReader'>
        <property name='auditModelUrl'>
           <value>classpath:alfresco/audit/alfresco-audit-repository.xml</value>
        </property>
        <property name='auditModelRegistry' ref='auditModel.modelRegistry'/>
    </bean>

Location (v3.3)


Audit configuration files are picked up automatically using the following search paths.


  • classpath*:alfresco/audit/*.xml
  • classpath*:alfresco/enterprise/audit/*.xml
  • classpath*:alfresco/module/*/audit/*.xml
  • classpath*:alfresco/extension/audit/*.xml

Structure


Audit configuration files are split into 4 basic sections:


<DataExtractors>


In this section, DataExtractors are declared for use in the <Application> sections of the configuration files.  A DataExtractor is a component that uses input data to produce some output, either transforming the data or merely outputting the data verbatim.  The simplest extractor is the SimpleValueDataExtractor, which returns whatever data is passed in.  A more complex extractor is the NodeNameDataExtractor, which is able to produce the cm:name value of a node, assuming the data passed in is a NodeRef.  For the complete set of built-in generators, see package org.alfresco.repo.audit.extractor or beans auditModel.extractor.* declared in alfresco/audit-services-context.xml.

The extractors can be declared in-line:



    <DataExtractors>
       <DataExtractor name='simpleValue' class='org.alfresco.repo.audit.extractor.SimpleValueDataExtractor'/>
       ...
    </DataExtractors>

or declared in Spring configuration and referenced in the audit configuration (see alfresco/audit-services-context.xml):



    <DataExtractors>
       <DataExtractor name='simpleValue' registeredName='auditModel.extractor.simpleValue'/>
       ...
    </DataExtractors>

<DataGenerators>


In this section, DataGenerators are declared for use in the <Application> sections of the configuration files.  A DataGenerator is a component that produces data without any input i.e. data is produced when a data path is active, but is independent of the values at that path.  Examples of generators are the AuthenticatedUserDataGenerator, which produces the name of the currently-authenticated user (user in context) and the AuthenticatedPersonDataGenerator, which produces the full name of the currently-authenticated user (person in context).  For the complete set of built-in generators, see package org.alfresco.repo.audit.generator or beans auditModel.generator.* declared in alfresco/audit-services-context.xml.

The generators can be declared in-line:



    <DataGenerators>
       <DataGenerator name='currentUser' class='org.alfresco.repo.audit.generator.AuthenticatedUserDataGenerator'/>
       <DataGenerator name='personFullName' class='org.alfresco.repo.audit.generator.AuthenticatedPersonDataGenerator'/>
    </DataGenerators>

or declared in Spring configuration and referenced in the audit configuration (see alfresco/audit-services-context.xml):



    <DataGenerators>
       <DataGenerator name='currentUser' registeredName='auditModel.generator.user'/>
       <DataGenerator name='personFullName' registeredName='auditModel.generator.personFullName'/>
    </DataGenerators>

<PathMappings>


The expanded map coming from the Data Producers is passed through the path mappings.  This is a raw remapping of the input data based on the path names in the data map.



    <PathMappings>
        <PathMap source='/DOD5015' target='/DOD5015'/>
        <PathMap source='/DOD5015/event/node' target='/DOD5015/event/person'/>
        <PathMap source='/alfresco-api/post/AuthenticationService/authenticate' target='/DOD5015/login'/>
    </PathMappings>

In this example, all paths starting with /DOD5015 are mapped verbatim, but without the declaration the data paths starting with /DOD5015 would be discarded.  Notice that a very small subset of the Alfresco API data is used (only the AuthenticationService.authenticate call) by mapping all values starting with that path to /DOD5015/login.


<Application>


This section defines how the mapped data is to be used by DataGenerators or by DataExtractors.



    <Application name='DOD5015' key='DOD5015'>
        <AuditPath key='login'>
            <AuditPath key='args'>
                <AuditPath key='userName'>
                    <RecordValue key='value' dataExtractor='simpleValue'/>
                </AuditPath>
            </AuditPath>
            <AuditPath key='no-error'>
                <GenerateValue key='fullName' dataGenerator='personFullName'/>
            </AuditPath>
            <AuditPath key='error'>
                <RecordValue key='value' dataExtractor='nullValue'/>
            </AuditPath>
        </AuditPath>
    </Application>

Built-in Data Producers


Public Service APIs


The public service APIs are still wrapped with the org.alfresco.repo.audit.AuditMethodInterceptor.  The Javadocs describe the data that is produced in more detail.


Sample Code


DEBUG Logging


To see which data is being produced, rejected or recorded, switch DEBUG for:

  org.alfresco.repo.audit.AuditComponentImpl=DEBUG

JUnit Code


There are few code samples that demonstrate usage of the new Audit APIs and configuration more succinctly than the unit test code:


  • org.alfresco.repo.audit.AuditComponentTest
    • alfresco-audit-test-authenticationservice.xml: This is used by the test to capture both successful and unsuccessful login attempts in the audit data.
    • testAuditAuthenticationService: This loads the audit configuration manually, but would be done using an AuditModelReader (mentioned earlier) in production.  The test also demonstrates the use of the auditSearch method.

DOD5015


The DOD5015 module pulls in audit data from the AuthenticationService but adds more data around the individual actions that take place during RM processes.


  • org.alfresco.module.org_alfresco_module_dod5015.audit.*
    • RecordsManagementAuditServiceImpl$RMAuditTxnListener: This transaction listener generates RM-specific data for events (it is a Data Producer).  It generates node property deltas, amongst other things.
    • config/alfresco/module/org_alfresco_module_dod5015/audit/rm-audit.xml: This defines how the data produced by the AuthenticationService and the DOD5015 module is persisted.  There are some custom DataGenerators and DataRecorders.
    • RecordsManagementAuditServiceImpl.getAuditTrailImpl: This method demonstrates how the RM use-case searches the audit data.  Further query extensions are required to extend the search filters available via the auditQuery API.




Note Regarding WCM


Web Projects automatically capture a full version history of all changes to all assets, via the snapshot history, without requiring additional auditing functionality.  This doesn't prevent data from being captured in any part of WCM or DM, but assset metadata history is automatically available in WCM.


Introduction


A new auditing framework was introduced in version V3.2r (DOD5015 Records Management) to incorporate expanded requirements.  The new framework introduces new features such as:


  • Data is stored in inherently searchable (database-indexed) tables specific to the type of data.
  • Any type of data can be produced and passed to the AuditComponent (free-form, interceptor-driven, ad-hoc).
  • Audit configuration is used to filter, transform and generate data for eventual storage.
  • Callback-driven query API.

As of 3.2r:


  • Auditing is enabled and disabled using a global property:
  # Audit configuration
  audit.enabled=false

  • The new implementation is not (yet) the default:
  audit.useNewConfig=true

As of 3.3:


  • With the default product settings in v3.3, the new and old auditing implementations are enabled in tandem to allow backwards compatibility with settings in config/auditConfig.xml. To exclusively use the new implementation and configuration described here, set the following in alfresco-global.properties:
  audit.useNewConfig=true

Architecture


812px

Data Producers include any components that produce data that might be audited.  Data producers do not need to know anything about how the data will be stored.  In short, data is produced and thrown at the AuditComponent.recordAuditValues.  The only requirement is that each packet of data is a Map of data keyed by logical path names, which are specific to the producers.

Although the AuditService search should be used for data retrieval, for completeness, the following tables are used:


  • Tables exclusive to the new audit (AlfrescoPostCreate-3.2-AuditTables.sql)
    • alf_audit_model: Audit configuration files are recorded here.
    • alf_audit_application: An entry for each logical application.  There may be several audit applications defined in a single audit model.
    • alf_audit_entry: Each call to AuditComponent.recordAuditValues will result in an entry here.  There is a reference to a property.
  • Shared tables (AlfrescoPostCreate-3.2-PropertyValueTables.sql)
    • alf_prop_root: Entry point for properties: shared values are fully indexed; arbitrarily-deep collections; quick data query and reconstruction.
    • etc.



Example audit data passed to recordAuditValues():



Root path:
   /alfresco-api/post/NodeService/createStore
Map:
   args/protocol = 'workspace'
   args/identifier = 'SpacesStore'
   result = StoreRef[workspace://SpacesStore]

If the root path passes the initial filtration phase - there is at least one component interested in auditing the information - then the map is expanded.

Example expanded audit data:



Map:
   /alfresco-api/post/NodeService/createStore/args/protocol = 'workspace'
   /alfresco-api/post/NodeService/createStore/args/identifier = 'SpacesStore'
   /alfresco-api/post/NodeService/createStore/result = StoreRef[workspace://SpacesStore]

The filtered data is then passed through the path mappings, generating a new Map of data for each application.

Example path-mapped audit data:



Map:
   /MyApp/createStore = StoreRef[workspace://SpacesStore]

This data is then passed to any extractors and generators to produce a final Map of data that will be persisted.

Example persisted audit data:



Map:
   /MyApp/createStore/value = StoreRef[workspace://SpacesStore]
   /MyApp/createStore/rootNode = NodeRef[workspace://SpacesStore/fd123...]

Data Configuration


Location (v3.2r)


Audit configuration files (XSD at /alfresco/audit/alfresco-audit-3.2.xsd) are loaded into a registry using an instance of AuditModelReader:



    <bean id='auditModel.repository' class='org.alfresco.repo.audit.model.AuditModelReader'>
        <property name='auditModelUrl'>
           <value>classpath:alfresco/audit/alfresco-audit-repository.xml</value>
        </property>
        <property name='auditModelRegistry' ref='auditModel.modelRegistry'/>
    </bean>

Location (v3.3)


Audit configuration files are picked up automatically using the following search paths.


  • classpath*:alfresco/audit/*.xml
  • classpath*:alfresco/enterprise/audit/*.xml
  • classpath*:alfresco/module/*/audit/*.xml
  • classpath*:alfresco/extension/audit/*.xml

Structure


Audit configuration files are split into 4 basic sections:


<DataExtractors>


In this section, DataExtractors are declared for use in the <Application> sections of the configuration files.  A DataExtractor is a component that uses input data to produce some output, either transforming the data or merely outputting the data verbatim.  The simplest extractor is the SimpleValueDataExtractor, which returns whatever data is passed in.  A more complex extractor is the NodeNameDataExtractor, which is able to produce the cm:name value of a node, assuming the data passed in is a NodeRef.  For the complete set of built-in generators, see package org.alfresco.repo.audit.extractor or beans auditModel.extractor.* declared in alfresco/audit-services-context.xml.

The extractors can be declared in-line:



    <DataExtractors>
       <DataExtractor name='simpleValue' class='org.alfresco.repo.audit.extractor.SimpleValueDataExtractor'/>
       ...
    </DataExtractors>

or declared in Spring configuration and referenced in the audit configuration (see alfresco/audit-services-context.xml):



    <DataExtractors>
       <DataExtractor name='simpleValue' registeredName='auditModel.extractor.simpleValue'/>
       ...
    </DataExtractors>

<DataGenerators>


In this section, DataGenerators are declared for use in the <Application> sections of the configuration files.  A DataGenerator is a component that produces data without any input i.e. data is produced when a data path is active, but is independent of the values at that path.  Examples of generators are the AuthenticatedUserDataGenerator, which produces the name of the currently-authenticated user (user in context) and the AuthenticatedPersonDataGenerator, which produces the full name of the currently-authenticated user (person in context).  For the complete set of built-in generators, see package org.alfresco.repo.audit.generator or beans auditModel.generator.* declared in alfresco/audit-services-context.xml.

The generators can be declared in-line:



    <DataGenerators>
       <DataGenerator name='currentUser' class='org.alfresco.repo.audit.generator.AuthenticatedUserDataGenerator'/>
       <DataGenerator name='personFullName' class='org.alfresco.repo.audit.generator.AuthenticatedPersonDataGenerator'/>
    </DataGenerators>

or declared in Spring configuration and referenced in the audit configuration (see alfresco/audit-services-context.xml):



    <DataGenerators>
       <DataGenerator name='currentUser' registeredName='auditModel.generator.user'/>
       <DataGenerator name='personFullName' registeredName='auditModel.generator.personFullName'/>
    </DataGenerators>

<PathMappings>


The expanded map coming from the Data Producers is passed through the path mappings.  This is a raw remapping of the input data based on the path names in the data map.



    <PathMappings>
        <PathMap source='/DOD5015' target='/DOD5015'/>
        <PathMap source='/DOD5015/event/node' target='/DOD5015/event/person'/>
        <PathMap source='/alfresco-api/post/AuthenticationService/authenticate' target='/DOD5015/login'/>
    </PathMappings>

In this example, all paths starting with /DOD5015 are mapped verbatim, but without the declaration the data paths starting with /DOD5015 would be discarded.  Notice that a very small subset of the Alfresco API data is used (only the AuthenticationService.authenticate call) by mapping all values starting with that path to /DOD5015/login.


<Application>


This section defines how the mapped data is to be used by DataGenerators or by DataExtractors.



    <Application name='DOD5015' key='DOD5015'>
        <AuditPath key='login'>
            <AuditPath key='args'>
                <AuditPath key='userName'>
                    <RecordValue key='value' dataExtractor='simpleValue'/>
                </AuditPath>
            </AuditPath>
            <AuditPath key='no-error'>
                <GenerateValue key='fullName' dataGenerator='personFullName'/>
            </AuditPath>
            <AuditPath key='error'>
                <RecordValue key='value' dataExtractor='nullValue'/>
            </AuditPath>
        </AuditPath>
    </Application>

Built-in Data Producers


Public Service APIs


The public service APIs are still wrapped with the org.alfresco.repo.audit.AuditMethodInterceptor.  The Javadocs describe the data that is produced in more detail.


Sample Code


DEBUG Logging


To see which data is being produced, rejected or recorded, switch DEBUG for:

  org.alfresco.repo.audit.AuditComponentImpl=DEBUG

JUnit Code


There are few code samples that demonstrate usage of the new Audit APIs and configuration more succinctly than the unit test code:


  • org.alfresco.repo.audit.AuditComponentTest
    • alfresco-audit-test-authenticationservice.xml: This is used by the test to capture both successful and unsuccessful login attempts in the audit data.
    • testAuditAuthenticationService: This loads the audit configuration manually, but would be done using an AuditModelReader (mentioned earlier) in production.  The test also demonstrates the use of the auditSearch method.

DOD5015


The DOD5015 module pulls in audit data from the AuthenticationService but adds more data around the individual actions that take place during RM processes.


  • org.alfresco.module.org_alfresco_module_dod5015.audit.*
    • RecordsManagementAuditServiceImpl$RMAuditTxnListener: This transaction listener generates RM-specific data for events (it is a Data Producer).  It generates node property deltas, amongst other things.
    • config/alfresco/module/org_alfresco_module_dod5015/audit/rm-audit.xml: This defines how the data produced by the AuthenticationService and the DOD5015 module is persisted.  There are some custom DataGenerators and DataRecorders.
    • RecordsManagementAuditServiceImpl.getAuditTrailImpl: This method demonstrates how the RM use-case searches the audit data.  Further query extensions are required to extend the search filters available via the auditQuery API.

Outcomes