reading from a request inputstream is unpredictable

Wed, Oct 7, 2009

I’ve been working on a Blackboard Building Block to automatically create users and enroll them on courses, driven via an Apache Camel/ActiveMQ messaging broker, so I wanted a way to start and stop the client, which is inside the block. As this isn’t course specific, I decided to expose a control page on the block and put Guanxi in front of it to Shibboleth enable the authentication to the block. It was simplicity itself. I added the Guard stuff to web.xml and the Guard to the pom, registered the new Guard with the Engine and IdP, rebuilt and installed the block and the WAYF kicked in when I went to the control page.

The problems started when the Engine POSTed the SAML to the Guard inside the block:

Guard ACS connection error
Server returned HTTP response code: 500 for URL: … guard.guanxiGuardACS
Much toing and froing later, inpsecting content lengths, parameter maps, java security permissions, tomcat logs, apache logs, IIS logs, Windows firewall, I eventually found the problem. To make sure I added a call to request.getParameterMap() in the Guard, which reproduced the problem I was seeing from within Blackboard. As soon as anything and I mean absolutely anything, calls methods on the request, it invalidates the InputStream, which doesn’t support reset. So the data is lost for ever.

Well, not quite. It’s in as a request parameter but the Engine was explicitly saving a SAML stream down the pipe, resulting in this weird parameter setup:

Debugging the Guanxi Guard

The POST data was split into key and value:

key = <?xml version
value = rest of the SOAP and SAML data
The data was there but I had no way to get to it. So I changed how the Engine sends the attributes to the Guard:
soapRequest.save(new ByteArrayOutputStream());
String soap = URLEncoder.encode(“soap”, “UTF-8”) + “=” +
  URLEncoder.encode(os.toString(), “UTF-8”);
OutputStreamWriter wr = new OutputStreamWriter(connection.getOutputStream());
wr.write(soap);
wr.flush();
and changed the Guard to load the SOAP/SAML from request.getParameter(“soap”);

These improvements will be in the next Engine and Guard release.

comments powered by Disqus