A skeletal example follows to demonstrate how to create a map to contain a custom field extraction rule: Adding custom fields to the audit log via audit.xml Code Block |
---|
| <!-- Adds a function to extract a custom field called MYFIELD after the final response has been generated. -->
<bean id="shibboleth.PostResponseAuditExtractors" parent="shibboleth.DefaultPostResponseAuditExtractors">
<property name="sourceMap">
<map merge="true">
<entry key="MYFIELD" value-ref="MyExtractionFunctionBean" />
</map>
</property>
</bean> |
A real world example: if you're logging fields containing a URL, you may need to escape characters in a URL because of the delimiter you choose to use in the log format. You can do this using a script: Encoding 'pipe' character appearing in CAS service URLs Code Block |
---|
| <bean id="shibboleth.CASValidationAuditExtractors" parent="shibboleth.DefaultCASValidationAuditExtractors" lazy-init="true">
<property name="sourceMap">
<map merge="true">
<entry>
<key>
<util:constant static-field="net.shibboleth.idp.cas.protocol.CASAuditFields.SERVICE_URL"/>
</key>
<bean parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript">
<constructor-arg>
<value>
<![CDATA[
var serviceLookupFunctionClass = Java.type("net.shibboleth.idp.cas.audit.impl.ServiceLookupFunction");
var serviceLookupFunction = new serviceLookupFunctionClass();
var service = serviceLookupFunction.apply(input);
if (service != null) {
var serviceNew = service.replace(/\|/g, '%7C');
}
else {
var serviceNew = null;
}
serviceNew;
]]>
</value>
</constructor-arg>
</bean>
</entry>
</map>
</property>
</bean> |
A rather more convoluted example is to dump the values or arbitrary attributes into the log. To do this we define an abstract bean to emit the attribute values (in an arbitrary format) for any attribute (most of this is really error and null handling): Output Attribute Values Code Block |
---|
| <bean id="AttributeValueExtraction" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript" abstract="true">
<constructor-arg>
<value>
<![CDATA[
var getinfo = function() {
var rpContext = input.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext");
if (null === rpContext) {
return null;
}
var attrContext = rpContext.getSubcontext("net.shibboleth.idp.attribute.context.AttributeContext");
if (null === attrContext) {
return null;
}
var attributes = null
attributes = attrContext.getUnfilteredIdPAttributes();
if (null === attributes) {
return null;
}
attribute = attributes.get(custom);
if (null === attribute || attribute.getValues().isEmpty()) {
return null;
}
var iter = attribute.getValues().iterator();
var result = "";
while (iter.hasNext()) {
result = result + " " + iter.next().toString();
}
return result;
}
getinfo();
]]>
</value>
</constructor-arg>
</bean> |
Then a bean to emit a specific attribute can be easily created: Code Block |
---|
| <bean id="EmailExtraction" parent="AttributeValueExtraction" p:customObject="mail" /> |
|