Using HTTP POST binding in OpenSAML 4

SAML messages can be sent using different methods, called bindings. There are four main standard bindings being used today, HTTP Redirect, HTTP POST, HTTP Artifact and SOAP.

This tutorial will walk you through how to send a message, specifically a authentication request, using HTTP POST in OpenSAML.

The HTTP POST binding

The Redirect binding explained here is a popular method of sending messages which relies on HTTP Redirects. A problem with the redirect binding is that the message is send inside URL parameters and URL parameters can not hold large amounts of data. This makes it suitable for SAML authentication request, which is quite small, but less suitable for large messages like SAML responses. The POST binding gives a solution to this.

The HTTP POST binding uses input fields in a HTML form to send SAML messages.

Diagram of POST binding

  1. When the SP or IdP want to send a message it responds to the current user with a HTML page with the SAML message encoded in a input field in a form.
  2. When the browser receives the HTML page a JavaScript or meta tag makes the browser automatically submit the form to the recipient of the message .
  3. When the user arrives with its submitted form at the receiver of the message, the receiver will pick the message from the request parameters and parse the message.

The HTML form explained

A typical POST binding HTML page look like this.

 1<html>
 2    <head>
 3        <meta charset="utf-8" />
 4    </head>
 5    <body onload="document.forms[0].submit()">
 6        <noscript>
 7            <p>
 8                <strong>Note:</strong> Since your browser does not support JavaScript,
 9                you must press the Continue button once to proceed.
10            </p>
11        </noscript>
12        <form action="http://localhost:8080/opensaml-http-post/receiverPage" method="post">
13            <div>
14<input type="hidden" name="RelayState" value="teststate"/>                
15<input type="hidden" name="SAMLRequest" value="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c2FtbDJwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1sMnA9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCIgQXNzZXJ0aW9uQ29uc3VtZXJTZXJ2aWNlVVJMPSJUaGUgc2hvdWxkIGJlIHRoZSBlbmRwb2ludCB0aGF0IHNob3VsZCByZWNpZXZlIHRoZSByZXN1bHQgb2YgdGhlIGF1dGhlbnRpY2F0aW9uIiBEZXN0aW5hdGlvbj0iaHR0cDovL2xvY2FsaG9zdDo4MDgwL29wZW5zYW1sLWh0dHAtcG9zdC9yZWNlaXZlclBhZ2UiIElEPSJfODczNjcwZDBlNmZiYTI0MDkzOWIwYjQ5OTJiOGRlMzEiIElzc3VlSW5zdGFudD0iMjAyMS0xMC0xNlQxODo0OTowOC4wODBaIiBQcm90b2NvbEJpbmRpbmc9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpiaW5kaW5nczpIVFRQLUFydGlmYWN0IiBWZXJzaW9uPSIyLjAiPjxzYW1sMjpJc3N1ZXIgeG1sbnM6c2FtbDI9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iPlRoaXMgc2hvdWxkIGJlIHRoZSBzZW5kZXIgZW50aXR5SWQ8L3NhbWwyOklzc3Vlcj48c2FtbDJwOk5hbWVJRFBvbGljeSBBbGxvd0NyZWF0ZT0idHJ1ZSIgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDp0cmFuc2llbnQiLz48L3NhbWwycDpBdXRoblJlcXVlc3Q+"/>                    
16            </div>
17            <noscript>
18                <div>
19                    <input type="submit" value="Continue"/>
20                </div>
21            </noscript>
22        </form>
23    </body>
24</html>

There are two fields used in this binding

  • SAMLRequest/SAMResponse - The encoded, unsigned message
  • RelayState - The relay state, sent in the original request and send back in the response

Sending a message using OpenSAML 4

Because this binding is creating a webpage, OpenSAML uses Apache Velocity. The velocity library must be included in the Maven Pom. If not you will get the following errror

1java.lang.RuntimeException: net.shibboleth.utilities.java.support.component.ComponentInitializationException: VelocityEngine must be supplied

Add this to pom.xml

1<dependency>
2    <groupId>org.apache.velocity</groupId>
3    <artifactId>velocity-engine-core</artifactId>
4    <version>${velocity.version}</version>
5</dependency>

Creating message contexts to set the message, relay state and receiving end point. Creating Velocity engine to handle web site creation.

 1MessageContext context = new MessageContext();
 2
 3context.setMessage(authnRequest);
 4
 5SAMLBindingContext bindingContext = context.getSubcontext(SAMLBindingContext.class, true);
 6bindingContext.setRelayState("teststate");
 7
 8SAMLPeerEntityContext peerEntityContext = context.getSubcontext(SAMLPeerEntityContext.class, true);
 9
10SAMLEndpointContext endpointContext = peerEntityContext.getSubcontext(SAMLEndpointContext.class, true);
11endpointContext.setEndpoint(URLToEndpoint(MESSAGE_RECEIVER_ENDPOINT));
12
13VelocityEngine velocityEngine = new VelocityEngine();
14velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADERS, "classpath");
15velocityEngine.setProperty("classpath.resource.loader.class",
16		"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
17velocityEngine.init();
Initializing HTTPPostEncoder, setting context and Velocity engine and sending the message.
1HTTPPostEncoder encoder = new HTTPPostEncoder();
2
3encoder.setMessageContext(context);
4encoder.setHttpServletResponse(httpServletResponse);
5encoder.setVelocityEngine(velocityEngine);
6
7encoder.initialize();
8encoder.encode();

Receiving a message using OpenSAML 4

Using HTTPPostDecoder to decode the received message from the HTTPServletRequest

1HTTPPostDecoder decoder = new HTTPPostDecoder();
2decoder.setHttpServletRequest(req);
3
4decoder.initialize();
5decoder.decode();
6
7MessageContext messageContext = decoder.getMessageContext();
8authnRequest = (AuthnRequest) messageContext.getMessage();

Get it on Github!

The full running sample is available on Github at https://github.com/rasmusson/OpenSAML-sample-code under opensaml-http-post

Just clone it, run it, go nuts!

1git clone https://github.com/rasmusson/OpenSAML-sample-code/
2cd opensaml-http-post
3mvn tomcat:run

All messages are printed in the console

Browse to http://localhost:8080/opensaml-http-post/postPage

Summary

In this post we have looked at.

  • The basics of the HTTP Post binding
  • Sending a message using OpenSAML 4
  • Receiving a message using OpenSAML 4