[ACCEPTED]-How do I correctly prepare an 'HTTP Redirect Binding' SAML Request using C#-sharpziplib

Accepted answer
Score: 14

I've just run the following code with your 24 example SAML:

        var saml = string.Format(sample, Guid.NewGuid());
        var bytes = Encoding.UTF8.GetBytes(saml);

        string middle;
        using (var output = new MemoryStream())
        {
            using (var zip = new DeflaterOutputStream(output))
                zip.Write(bytes, 0, bytes.Length);

            middle = Convert.ToBase64String(output.ToArray());
        }

        string decoded;
        using (var input = new MemoryStream(Convert.FromBase64String(middle)))
        using (var unzip = new InflaterInputStream(input))
        using (var reader = new StreamReader(unzip, Encoding.UTF8))
            decoded = reader.ReadToEnd();

        bool test = decoded == saml;

The test variable is true. This 23 means that the zip/base64/unbase64/unzip 22 roundtrip performs correctly. The error 21 must occur later. Maybe the URLEncoder destroys 20 them? Could you try similar urlencode/decode 19 test? Also, check how long the result is. It 18 may be possible that the resulting URL is 17 truncated due to its length.

(edit: I've 16 added a StreamReader instead of reading 15 to arrays. Earlier my sample used bytes.Length 14 to prepare the buffer and that could damage 13 the test. Now the reading uses only the 12 information from the compressed stream)

edit:

        var saml = string.Format(sample, Guid.NewGuid());
        var bytes = Encoding.UTF8.GetBytes(saml);

        string middle;
        using (var output = new MemoryStream())
        {
            using (var zip = new DeflateStream(output, CompressionMode.Compress))
                zip.Write(bytes, 0, bytes.Length);

            middle = Convert.ToBase64String(output.ToArray());
        }

        // MIDDLE is the thing that should be now UrlEncode'd

        string decoded;
        using (var input = new MemoryStream(Convert.FromBase64String(middle)))
        using (var unzip = new DeflateStream(input, CompressionMode.Decompress))
        using (var reader = new StreamReader(unzip, Encoding.UTF8))
            decoded = reader.ReadToEnd();

        bool test = decoded == saml;

this 11 code produces a middle variable, that once is 10 UrlEncoded, passes through the debugger 9 properly. DeflateStream comes from the standard .Net's 8 System.IO.Compression namespace. I don't have the slightest idea 7 why the SharpZip's Deflate is not accepted 6 by the 'debugger' site. It is undeniable 5 that the compression works, as it manages 4 to decompress the data properly.. it just 3 has to be some difference in the algorithms, but 2 I cannot tell what is the difference between 1 this deflate and that deflate, d'oh.

Score: 13

The question at the top contains a "Decode 8 SAMLResponse - Working Code" section, but 7 that code seemed broken. After trying a 6 few things, I discovered that it was trying 5 to read and write to the same stream at 4 the same time. I reworked it by separating 3 the read and write streams and here is my 2 solution (I am providing the request section 1 for convenience and clarity):

Encode SAML Authentication Request:

public static string EncodeSamlAuthnRequest(this string authnRequest) {
    var bytes = Encoding.UTF8.GetBytes(authnRequest);
    using (var output = new MemoryStream()) {
      using (var zip = new DeflateStream(output, CompressionMode.Compress)) {
        zip.Write(bytes, 0, bytes.Length);
      }
      var base64 = Convert.ToBase64String(output.ToArray());
      return HttpUtility.UrlEncode(base64);
    }
  }

Decode SAML Authentication Response:

public static string DecodeSamlAuthnRequest(this string encodedAuthnRequest) {
  var utf8 = Encoding.UTF8;
  var bytes = Convert.FromBase64String(HttpUtility.UrlDecode(encodedAuthnRequest));
  using (var output = new MemoryStream()) {
    using (var input = new MemoryStream(bytes)) {
      using (var unzip = new DeflateStream(input, CompressionMode.Decompress)) {
        unzip.CopyTo(output, bytes.Length);
        unzip.Close();
      }
      return utf8.GetString(output.ToArray());
    }
  }
}

More Related questions