2 Replies Latest reply on May 16, 2016 2:58 PM by Tim357

    Deciphering a SAML Message in ColdFusion

    KomputerMan.com Level 1

      I'm working on an SSO solution for a client.  At this time I'm able to encode an authentication message and successfully send it to the ADFS server.  The ADFS server handles my login and then returns to my site with an HTTP-POST response.  In the POST there is an ADFS encoded SAML message I need to decipher.  I found a few samples of code but none have worked.  This one seemed to have the most promise but...

       

      <cfscript>

      // Decode the query string from Base 64 

        Decoder = CreateObject("Java", "sun.misc.BASE64Decoder").init();

        SamlByte = Decoder.decodeBuffer(Form.SAMLResponse);

       

      // Create Byte Array used for the inflation, the CF way 

        ByteClass = CreateObject("Java", "java.lang.Byte").TYPE;

        ByteArray = CreateObject("Java", "java.lang.reflect.Array").NewInstance(ByteClass, 1024);

       

      // Create Byte Streams needed for inflation

        ByteIn   = CreateObject("Java", "java.io.ByteArrayInputStream").init(SamlByte);

        ByteOut  = CreateObject("Java", "java.io.ByteArrayOutputStream").init();

       

      // Create Objects needed for inflation 

        Inflater = CreateObject("Java", "java.util.zip.Inflater").init(true);

        InflaterStream = CreateObject("Java", "java.util.zip.InflaterInputStream").init(ByteIn, Inflater);

       

      // Complete the inflation 

        Count = InflaterStream.read(ByteArray);

        while (Count != -1) {

        ByteOut.write(ByteArray, 0, Count);

        Count = InflaterStream.read(ByteArray);

        }

       

      // Finished with inflation 

        Inflater.end();

        InflaterStream.close();

       

      // Convert SAML request back to a string 

        SamlString = CreateObject("Java", "java.lang.String").init(ByteOut.toByteArray());

        </cfscript>

       

      When the code get to the Count = InflaterStream.read(ByteArray); statement the following error message is returned: oversubscribed dynamic bit lengths tree

       

      My question is does anybody have a snippet of code that is used to successfully decipher an ADFS encoded SAML response?

        • 1. Re: Deciphering a SAML Message in ColdFusion
          Tim357

          I'm working on the same problem.  I'm using this function, but it doesn't work either.  I've figured out that the problem is Java's gzip file is valid (it has a 10-byte header, and a 8-byte trailer), but the ADFS one is missing both of those (it only contains the content).  while it's easy to chop off the the first 10 bytes and the last 8-bytes to send ADFS what it's expecting, it's not possible (as far as I can tell) to derive the last 8 bytes without having the decompressed file.

           

          <cffunction name="ungzip" returntype="string">       <cfargument name="encodedString" type="string" required="true">       <cfargument name="encoding" type="string" default="Base64">       <cfscript>            var line = "";            if( ListContains("Base64,Hex,UU", encoding) ) {                 var data = BinaryDecode(encodedString, encoding);                  var buffReader = createObject("java", "java.io.BufferedReader").init(                                         createObject("java", "java.io.InputStreamReader").init(                                             createObject("java", "java.util.zip.GZIPInputStream").init(                                                 createObject("java", "java.io.ByteArrayInputStream").init(data)                                             )                                         )                                     );                 line = buffReader.readLine();                 buffReader.close();            }             return line;       </cfscript>  </cffunction>

           

          Did you ever get something figured out?

          • 2. Re: Deciphering a SAML Message in ColdFusion
            Tim357 Level 1

            I found this code, which works.  Reading, decoding and inflating a SAML XML respone with Coldfusion · GitHub

             

            The key here is using InflateInputStream, and specifying the Inflater with the nowrap parameter set to true, so it leaves out the header and footer info I mentioned above.

             

            [edit:] Looking at the code you posted, it's the same, except for how you're converting the base64 string to binary.  Use coldfusion's built in function for this:

             

            SamlByte = ToBinary(Form.SAMLResponse);

             

            or

             

            SamlByte = BinaryDecode(Form.SAMLRespone, "Base64");