Can't decode saml message from shibboleth SP - invalid byte 1 of 1-byte UTF-8 sequence - java

64 Views Asked by At

In some installations we have a Service Provider Shibboleth Sp v3 and a Shibbleth idp V4 and all works fine.

For some reasons in an other environments we have to rely on a customized idp that we are writing in java (a sort of proxy between different sp and different third party idps), we still have the shibboleth service providers v3 like in the other environment, but this time they call our custom idp instead of the shibboleth one.

Usually in our custom idp we handle saml messages like this:

String samlmessage = request.getParameter("SAMLResponse");

or

String samlmessage = request.getParameter("SAMLRequest");

Where "request" is an javax.servlet.http.HttpServletRequest object.

And decode it in this manner:

byte[] base64DecodedMessagge = Base64.decodeBase64(samlmessage);
ByteArrayInputStream is = new ByteArrayInputStream(base64DecodedMessagge);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(is);
etc.

We have a problem decoding the logout request sent by the shibboleth sp to our idp:

At this instruction:

Document document = docBuilder.parse(is);

this exception is raised:

org.apache.xerces.impl.io.MalformedByteSequenceException: Invalid byte 1 of 1-byte UTF-8 sequence.

(note that for example decoding with the same code the authentication response of the third party idp does not raise this exception)

With saml tracer I see the saml of all messages, also the one that in java gives me the exception.

But if I take the value of these parameters (always from saml tracer), for example:

SAMLResponse: PHNhbWxwOlJlc3BvbnNlIER...etc etc

SAMLRequest: nVNdb6JAFP0rhNdGgUGFTtSE...etc etc

and i test in a decoder like this with utf-8:

https://www.base64decode.org/

Are decoded except the one that in java gives me an exception.

If saml tracer shows me the saml message value, it somehow managed to decode it..where am I wrong in the decoding? Is there a way to write equivalent code with opensaml libraries and have more reliable code in decoding?

Thanks for any helps.

1

There are 1 best solutions below

0
On

I found a solution, based on this :

https://stackoverflow.com/a/60813998/3147345

Instead of using:

byte[] base64DecodedMessagge = org.apache.commons.codec.binary.Base64.Base64.decodeBase64(samlmessage);
ByteArrayInputStream is = new ByteArrayInputStream(base64DecodedMessagge);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(is);
etc.

I used for this particular message:

byte[] decodedMessage = org.apache.xml.security.utils.Base64.decode(samlmessage);

byte[] inflatedData = new byte[(10 * decodedMessage.length)];
Inflater decompresser = new Inflater(true);
decompresser.setInput(decodedMessage, 0, decodedMessage.length);
int inflatedBytesLength = decompresser.inflate(inflatedData);
decompresser.end();
String inflated  = new String(inflatedData, 0, inflatedBytesLength);
ByteArrayInputStream is = new ByteArrayInputStream(inflated.getBytes());
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = docBuilder.parse(is);
etc.