Tuesday, April 28, 2015

NextReports Server: Audits at your hand

By default NextReports Server outputs some events to log files with following action names:
  • Sign in
  • Sign in failed
  • Sign out
  • Add entity
  • Modify entity
  • Delete entity
  • Copy entity
  • Move entity
  • Rename entity
  • Restore entity
  • Grant user / group
  • Revoke user / group
  • Run report
These events have some common properties like id, date, user name, action,session, ip, level (0=info, 1=error), error message. For some events there are also other properties. For example for "Run report" there are report path and duration; for "Grant user" there are entity path, user name to grant for, permissions and recursive flag.

NextReports Server has an extensible auditor feature. A database auditor can be defined to save all these events inside a database. This is very important because NextReports can generate reports over that database to get valuable information.

Inside securityContext.xml there is a bean called auditor:
 <bean class="ro.nextreports.server.audit.CompoundAuditor" id="auditor">
        <property name="auditors">
            <list>
                <ref bean="logAuditor"/>
            </list>
        </property>
</bean>
          

In this list, besides the log auditor we can add a database auditor:

<bean class="ro.nextreports.server.audit.CompoundAuditor" id="auditor">        
        <property name="auditors">             
           <list>
                 <ref bean="logAuditor"/>
                 <ref bean="dbAuditor"/> 
            </list>
        </property>
</bean>       
  
<bean class="ro.nextreports.server.audit.MySqlAuditor" id="dbAuditor">
         <property name="dataSource" ref="auditDataSource"/>
</bean>
   
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="auditDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>      
      <property name="url" value=""/>
      <property name="username" value=""/>
      <property name="password" value=""/>
</bean>

The database behind must contain two tables and a sequence:
  • NS_AUDIT (EVENT_ID, EVENT_DATE, EVENT_USERNAME, EVENT_ACTION, EVENT_SESSION, EVENT_IP, EVENT_LEVEL, EVENT_ERROR_MESSAGE)
  • NS_AUDIT_CONTEXT (EVENT_ID, EVENT_NAME, EVENT_VALUE)
  • NS_AUDIT_SEQ
As stated before, common properties will be saved inside NS_AUDIT, while specific event properties will be saved inside NS_AUDIT_CONTEXT.

For example, for a MySql database we need to call following sqls to initialize:

CREATE TABLE NS_AUDIT (
  EVENT_ID INT UNSIGNED NOT NULL, 
  EVENT_DATE TIMESTAMP, 
  EVENT_USERNAME VARCHAR(50), 
  EVENT_ACTION VARCHAR(30),
  EVENT_SESSION VARCHAR(100), 
  EVENT_IP VARCHAR(20), 
  EVENT_LEVEL  INT(2) , 
  EVENT_ERROR_MESSAGE VARCHAR(150)
) 

CREATE TABLE NS_AUDIT_CONTEXT (
  EVENT_ID INT UNSIGNED, 
  EVENT_NAME VARCHAR(50), 
  EVENT_VALUE VARCHAR(200)
) 
 
CREATE TABLE NS_AUDIT_SEQ( 
  EVENT_ID INT UNSIGNED  NOT NULL,
  CONSTRAINT event_pk PRIMARY KEY (EVENT_ID)
)

INSERT INTO NS_AUDIT_SEQ (EVENT_ID) VALUES(0) 

You should also create an index on EVENT_ID column from NS_AUDIT.

No comments: