Auditing and Statistics Via Inspektr
New CAS documentation site
CAS documentation has moved over to jasig.github.io/cas, starting with CAS version 4.x. The wiki will no longer be maintained. For the most recent version of the documentation, please refer to the aforementioned link.
The following configuration provides for database-backed auditing and statistics for CAS using the Inspektr Java library. The configuration assumes there exists a bean named "dataSource" that implements javax.sql.DataSource
defined somewhere in the Spring application context, e.g. deployerConfigContext.xml:
... <!-- This is a c3p0 pooled data source suitable for production environments. The use of some sort of connection pooling (c3p0, commons-pool) is strongly recommended for production use. --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" p:driverClass="oracle.jdbc.driver.OracleDriver" p:jdbcUrl="${database.url}" p:user="${database.user}" p:password="${database.password}" p:initialPoolSize="${database.pool.minSize}" p:minPoolSize="${database.pool.minSize}" p:maxPoolSize="${database.pool.maxSize}" p:maxIdleTimeExcessConnections="${database.pool.maxIdleTime}" p:checkoutTimeout="${database.pool.maxWait}" p:acquireIncrement="${database.pool.acquireIncrement}" p:acquireRetryAttempts="${database.pool.acquireRetryAttempts}" p:acquireRetryDelay="${database.pool.acquireRetryDelay}" p:idleConnectionTestPeriod="${database.pool.idleConnectionTestPeriod}" p:preferredTestQuery="select 1 from dual" /> ...
The configuration below is the suggested configuration up until CAS 3.4. In CAS 3.4, the configuration changed. See the configuration further below.
The following configuration is based on the auditTrailContext.xml file in WEB-INF/unused-spring-configuration/auditTrailContext.xml in the CAS 3.3.1 distribution WAR archive. The following configuration must be placed in an XML file in WEB-INF/spring-configuration of the WAR file deployed in your environment; a Maven WAR Overlay is a convenient way to do this in a repeatable fashion.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <description> Configuration file for the Inspektr package which handles auditing and statistics for Java applications. </description> <aop:aspectj-autoproxy/> <bean id="inspektrTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> <bean id="inspektrTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" p:transactionManager-ref="inspektrTransactionManager" p:isolationLevelName="ISOLATION_READ_COMMITTED" p:propagationBehaviorName="PROPAGATION_REQUIRED" p:timeout="5" /> <bean id="statisticManagementAspect" class="org.inspektr.statistics.StatisticManagementAspect"> <constructor-arg index="0"> <list> <bean class="org.inspektr.statistics.support.JdbcStatisticManager"> <constructor-arg index="0" ref="dataSource" /> <constructor-arg index="1" ref="inspektrTransactionTemplate" /> </bean> </list> </constructor-arg> <constructor-arg index="1" value="CAS" /> </bean> <bean id="auditTrailManagementAspect" class="org.inspektr.audit.AuditTrailManagementAspect"> <constructor-arg index="0" ref="auditablePrincipalResolver" /> <constructor-arg index="1"> <list> <bean class="org.jasig.cas.audit.spi.CredentialsAsFirstParameterResourceResolver" /> <bean class="org.jasig.cas.audit.spi.TicketAsFirstParameterResourceResolver" /> <bean class="org.jasig.cas.audit.spi.ServiceResourceResolver" /> </list> </constructor-arg> <constructor-arg index="2" ref="auditTrailManager"> </constructor-arg> <constructor-arg index="3" value="CAS" /> </bean> <bean id="auditTrailManager" class="org.inspektr.audit.support.JdbcAuditTrailManager"> <constructor-arg index="0" ref="inspektrTransactionTemplate" /> <property name="dataSource" ref="dataSource" /> </bean> <bean id="auditablePrincipalResolver" class="org.jasig.cas.audit.spi.TicketOrCredentialBasedAuditablePrincipalResolver"> <constructor-arg index="0" ref="ticketRegistry" /> </bean> </beans>
This is the configuration for CAS 3.4
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <description> Configuration file for the Inspektr package which handles auditing for Java applications. If enabled this should be modified to log audit and statistics information the same way your local applications do. The default is currently to log to the console which is good for debugging/testing purposes. </description> <aop:aspectj-autoproxy/> <bean id="auditTrailManagementAspect" class="com.github.inspektr.audit.AuditTrailManagementAspect"> <!-- String applicationCode --> <constructor-arg index="0" value="CAS" /> <!-- PrincipalResolver auditablePrincipalResolver --> <constructor-arg index="1" ref="auditablePrincipalResolver" /> <!-- List<AuditTrailManager> auditTrailManagers --> <constructor-arg index="2"> <list> <bean class="com.github.inspektr.audit.support.ConsoleAuditTrailManager" /> <!-- Uncomment following for writing logs to database via JDBC. See below for definition of auditManager bean. --> <!-- <ref local="auditManager" /> --> </list> </constructor-arg> <!-- Map<String,AuditActionResolver> auditActionResolverMap --> <constructor-arg index="3"> <map> <entry key="AUTHENTICATION_RESOLVER"> <ref local="authenticationActionResolver" /> </entry> <entry key="CREATE_TICKET_GRANTING_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="DESTROY_TICKET_GRANTING_TICKET_RESOLVER"> <bean class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver" /> </entry> <entry key="GRANT_SERVICE_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="GRANT_PROXY_GRANTING_TICKET_RESOLVER"> <ref local="ticketCreationActionResolver" /> </entry> <entry key="VALIDATE_SERVICE_TICKET_RESOLVER"> <ref local="ticketValidationActionResolver" /> </entry> </map> </constructor-arg> <!-- Map<String,AuditResourceResolver> auditResourceResolverMap --> <constructor-arg index="4"> <map> <entry key="AUTHENTICATION_RESOURCE_RESOLVER"> <bean class="org.jasig.cas.audit.spi.CredentialsAsFirstParameterResourceResolver" /> </entry> <entry key="CREATE_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="returnValueResourceResolver" /> </entry> <entry key="DESTROY_TICKET_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="ticketResourceResolver" /> </entry> <entry key="GRANT_SERVICE_TICKET_RESOURCE_RESOLVER"> <bean class="org.jasig.cas.audit.spi.ServiceResourceResolver" /> </entry> <entry key="GRANT_PROXY_GRANTING_TICKET_RESOURCE_RESOLVER"> <ref local="returnValueResourceResolver" /> </entry> <entry key="VALIDATE_SERVICE_TICKET_RESOURCE_RESOLVER"> <ref local="ticketResourceResolver" /> </entry> </map> </constructor-arg> </bean> <bean id="auditablePrincipalResolver" class="org.jasig.cas.audit.spi.TicketOrCredentialPrincipalResolver"> <constructor-arg index="0" ref="ticketRegistry" /> </bean> <bean id="authenticationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="_SUCCESS" /> <!-- String failureSuffix --> <constructor-arg index="1" value="_FAILED" /> </bean> <bean id="ticketCreationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="_CREATED" /> <!-- String failureSuffix --> <constructor-arg index="1" value="_NOT_CREATED" /> </bean> <bean id="ticketValidationActionResolver" class="com.github.inspektr.audit.spi.support.DefaultAuditActionResolver"> <!-- String successSuffix --> <constructor-arg index="0" value="D" /> <!-- String failureSuffix --> <constructor-arg index="1" value="_FAILED" /> </bean> <bean id="returnValueResourceResolver" class="com.github.inspektr.audit.spi.support.ReturnValueAsStringResourceResolver" /> <bean id="ticketResourceResolver" class="org.jasig.cas.audit.spi.TicketAsFirstParameterResourceResolver" /> <!-- Uncomment following beans for JDBC support. Assumes there is a dataSource bean that defines a valid JDBC data source. --> <!-- <bean id="inspektrTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" /> <bean id="inspektrTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate" p:transactionManager-ref="inspektrTransactionManager" p:isolationLevelName="ISOLATION_READ_COMMITTED" p:propagationBehaviorName="PROPAGATION_REQUIRED" /> <bean id="auditManager" class="com.github.inspektr.audit.support.JdbcAuditTrailManager"> <constructor-arg index="0" ref="inspektrTransactionTemplate" /> <property name="dataSource" ref="dataSource" /> </bean> --> </beans>
Inspektr assumes the database pointed to by the JDBC data source contains tables with the schema described at http://code.google.com/p/inspektr/wiki/DatabaseTables. The following script will create these tables with reasonable indices in Oracle; modify as needed for your database platform.
CREATE TABLE "COM_AUDIT_TRAIL" ( "AUD_USER" VARCHAR2(100) NOT NULL ENABLE, "AUD_CLIENT_IP" VARCHAR(15) NOT NULL ENABLE, "AUD_SERVER_IP" VARCHAR(15) NOT NULL ENABLE, "AUD_RESOURCE" VARCHAR2(100) NOT NULL ENABLE, "AUD_ACTION" VARCHAR2(100) NOT NULL ENABLE, "APPLIC_CD" VARCHAR2(5) NOT NULL ENABLE, "AUD_DATE" TIMESTAMP NOT NULL ENABLE ); ALTER TABLE "COM_AUDIT_TRAIL" ADD CONSTRAINT "COM_AUDIT_TRAIL_PK" PRIMARY KEY ( "AUD_USER", "AUD_CLIENT_IP", "AUD_SERVER_IP", "AUD_RESOURCE", "AUD_ACTION", "APPLIC_CD", "AUD_DATE" ) ENABLE; CREATE TABLE "COM_STATISTICS" ( "STAT_SERVER_IP" VARCHAR2(15) NOT NULL ENABLE, "STAT_DATE" DATE NOT NULL ENABLE, "APPLIC_CD" VARCHAR2(5) NOT NULL ENABLE, "STAT_PRECISION" VARCHAR2(6) NOT NULL ENABLE, "STAT_COUNT" NUMBER NOT NULL ENABLE, "STAT_NAME" VARCHAR2(100) ); ALTER TABLE "COM_STATISTICS" ADD CONSTRAINT "COM_STATISTICS_PK" PRIMARY KEY ( "STAT_SERVER_IP", "STAT_DATE", "APPLIC_CD", "STAT_PRECISION", "STAT_NAME" ) ENABLE; CREATE INDEX "COM_AUDIT_TRAIL_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_DATE"); CREATE INDEX "COM_AUDIT_TRAIL_CLIENT_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_CLIENT_IP", "AUD_DATE"); CREATE INDEX "COM_AUDIT_TRAIL_USER_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_USER", "AUD_DATE"); CREATE INDEX "COM_AUDIT_TRAIL_ACTION_DATE_I" ON "COM_AUDIT_TRAIL" ("AUD_ACTION", "AUD_DATE"); CREATE INDEX "COM_STATISTICS_DATE_I" ON "COM_STATISTICS" ("STAT_DATE"); CREATE INDEX "COM_STATISTICS_NAME_DATE_I" ON "COM_STATISTICS" ("STAT_NAME", "STAT_DATE");
Automatic Cleaning
If you're using the JdbcAuditTrailManager, you might want to automatically clean the audit log. Here's some example code (for your auditTrailContext.xml) that cleans out entries older than 180 days. This has been tested in CAS 3.4.10.
<bean id="auditManager" class="com.github.inspektr.audit.support.JdbcAuditTrailManager"> <constructor-arg index="0" ref="inspektrTransactionTemplate" /> <property name="dataSource" ref="dataSource" /> <property name="cleanupCriteria" ref="auditCleanupCriteria" /> </bean> <bean id="auditCleanupCriteria" class="com.github.inspektr.audit.support.MaxAgeWhereClauseMatchCriteria"> <constructor-arg index="0" value="180" /> </bean>