IdPErrorVelocity
Error Handling with Velocity
The default error handling behavior in the IdP relies on a JSP page to display errors to the user. This requires reinstalling and restarting the IdP to make changes to the error handling or the look and feel of the page.
The IdP includes an alternative error handler plugin that allows a Velocity macro template to be used instead. A few small changes are required to enable effective use of this plugin. Do not take the examples literally. Your XML may be different depending on the namespace prefixes (or lack thereof) in your files.
In place of the default <ph:ErrorHandler>
element in handler.xml something like the following is used:
<ph:ErrorHandler xsi:type="ph:VelocityErrorHandler" errorTemplatePath="error.vt" velocityEngine="shibboleth.MyVelocityEngine"/>
The reference to the velocity engine is an example. It must contain the ID of a bean you define in a custom Spring configuration file such as the following:
<?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:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd" > <bean id="shibboleth.MyVelocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean" depends-on="shibboleth.LogbackLogging"> <property name="overrideLogging" value="false"/> <property name="velocityProperties"> <props> <prop key="runtime.log.logsystem.class"> edu.internet2.middleware.shibboleth.common.util.Slf4JLogChute </prop> <prop key="resource.loader">file</prop> <prop key="file.resource.loader.class"> org.apache.velocity.runtime.resource.loader.FileResourceLoader </prop> <prop key="file.resource.loader.path">/opt/shibboleth-idp/conf</prop> <prop key="file.resource.loader.cache">false</prop> </props> </property> </bean> </beans>
Now you need to add your custom Spring configuration to the IdP's deployment descriptor:
<context-param> <param-name>contextConfigLocation</param-name> <param-value>$IDP_HOME$/conf/internal.xml; $IDP_HOME$/conf/service.xml; $IDP_HOME$/conf/myext.xml</param-value> </context-param>
Note that the web.xml file contains a couple of additional JSP page definitions as custom respones for 404 and 500 errors. You may wish to comment those out and use web server-wide configuration for those errors to avoid additional in-warfile error pages.
The error template itself is a standard Velocity macro template but lives in the file system and will be reloaded on every use. (You can enable caching of the file by modifying the relevant property in the bean definition.) Like the original JSP option, objects are available for interrogation by the template:
$request
- TheÂ
HttpServletRequest
being processed by the IdP when the error occurred.
- TheÂ
$requestError
- The exception object thrown by the IdP. This may be a wrapper around the actual error object, which will be available viaÂ
$requestError.getCause()
- The exception object thrown by the IdP. This may be a wrapper around the actual error object, which will be available viaÂ
$encoder
- An ESAPI encoder instance for use in properly encoding anything inserted into the template. Always use a proper encoder method such asÂ
$encoder.encodeForHTML()
when generating output.
- An ESAPI encoder instance for use in properly encoding anything inserted into the template. Always use a proper encoder method such asÂ
In principle, you could add additional IdP objects into the error handling context, if you needed them, by modifying edu/internet2/middleware/shibboleth/common/profile/provider/VelocityErrorHandler.java in the java-shib-common project, or copying that to your own IdP extension as the basis of your own error handler.
An example error template follows. This is based on a template used at Ohio State to handle a variety of common errors with special display logic. The IdP currently does not provide a good way to test for specialized errors, so this example relies on the technique of direct comparison of error messages. Be warned that those messages could change across releases, even patches. They are not a public API.