Customizing SAML Binding Templates
Some of the common SAML message transmission bindings include "transition" pages that perform automatic form submission with Javascript. Because of the usual network delays, as well as lag caused by slow applications, users may be paused on these pages for a few seconds at times, or occasionally even hung up by them, so it can be useful to customize the pages to provide explanatory material, custom branding, or just give people a way to recover. Another use case involves the injection of tracking bugs for statistical purposes.
Like the rest of the IdP's views, these templates use the Velocity template language and can be fully overridden if desired. It's also possible to provide header and body content that will be inserted into the existing templates, which may be sufficient in many cases.
The particular bindings typically involved are the SAML1 and SAML2 POST bindings, and less commonly the SAML2 Artifact and POST-SimpleSign bindings.
The template path where the bindings look for these templates is simply rooted in templates/ and any location on the Velocity search path can be used. This is typically the Java classpath overlaid by the views/ folder in the IdP's configuration tree.
In other words, to override templates/saml2-post-binding.vm, you can create a file named views/templates/saml2-post-binding.vm
(path relative to idp.home).
You can find all the templates inside the opensaml-saml-impl.jar library if you want to examine or copy them (the exact version of the jar filename will vary):
$ jar tf webapp/WEB-INF/lib/opensaml-saml-impl-5.0.0.jar | grep templates
templates/
templates/add-html-body-content.vm
templates/add-html-head-content.vm
templates/saml1-post-binding.vm
templates/saml2-post-artifact-binding.vm
templates/saml2-post-binding.vm
templates/saml2-post-simplesign-binding.vm
The two additions you can make to the default Velocity templates without replacing them are to add HTML markup (actually, Velocity Template Language, which can be a mix of standard HTML markup and Velocity statements) to the <head>
section, and/or to add HTML(VTL) markup to the <body>
section. You do that by creating one or both of the following files (again relative to idp.home):
views/templates/add-html-head-content.vm
views/templates/add-html-body-content.vm
Examples
Using "add-html-head-content.vm"
One reason you might want to add additional content to the Head section of the POST response page would be if you wanted to use something like Google Analytics (GA) to generate statistics about the usage of your Identity Provider, GA can provide the ability to generate useful statistics of how many logins are processed by your IdP, by SP etc. (Just keep in mind that GA will write out various cookies to the user's browser, and you probably want to read up about those cookies, how they are used, and what the default lifetime is for each. By including the appropriate directives, you can control the lifetime and usage of those cookies, at least to some extent.)
Here is sample content you could have for the "add-html-head-content.vm" file that would send info to GA every time your IdP POSTed a response to the user's browser:
##
## Velocity Template for sending information to Google Analytics
##
<script type="text/javascript">
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-your_key_here']);
_gaq.push(['_trackPageview']);
## Cookie session timeout in milliseconds
_gaq.push(['_setSessionCookieTimeout', 120000]);
var decodedaction = htmlDecode('${action}');
## Get the SAML Binding type
_gaq.push(['_trackEvent', 'SSOpage', '${SAMLBinding}', decodedaction]);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
Using "add-html-body-content.vm"
Here is a very simple example of sample content you could have for the "add-html-body-content.vm" file that would display a particular message to the user, which you might want to do in case network delays cause this page to be displayed to the user long enough that the user wonders what is happening next. Normally, this page is "auto-submitted" quickly enough that the user never really sees it. But if that doesn't happen, you may decide to craft a message to display to the user.
##
## Velocity Template for adding a message to the BODY of the response page
##
<strong> This form will autopost if you have JavaScript on,
but sometimes there can be slight delay. </strong>