¿Cómo preparo correctamente una solicitud SAML de 'Enlace de redireccionamiento HTTP' usando C #?

Necesito crear una transacción de autenticación SAML 2.0 iniciada por SP utilizando el método de enlace de redireccionamiento HTTP. Resulta que esto es bastante fácil. Solo obtenga el URI de IdP y concatene un solo parámetro de cadena de consultaSAMLRequest. El parámetro es un bloque codificado de xml que describe la solicitud SAML. Hasta ahora tan bueno.

El problema viene al convertir el SAML en el parámetro de cadena de consulta. Creo que este proceso de preparación debe ser:

Construye una cadena SAMLComprimir esta cadenaBase64 codifica la cadenaUrlcifre la cadena.

La solicitud SAML

<samlp:AuthnRequest
    xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
    ID="{0}"
    Version="2.0"
    AssertionConsumerServiceIndex="0"
    AttributeConsumingServiceIndex="0">
    <saml:Issuer>URN:xx-xx-xx</saml:Issuer>
    <samlp:NameIDPolicy
        AllowCreate="true"
        Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>

El código

private string GetSAMLHttpRedirectUri(string idpUri)
{
    var saml = string.Format(SAMLRequest, Guid.NewGuid());
    var bytes = Encoding.UTF8.GetBytes(saml);
    using (var output = new MemoryStream())
    {
        using (var zip = new DeflaterOutputStream(output))
        {
            zip.Write(bytes, 0, bytes.Length);
        }
        var base64 = Convert.ToBase64String(output.ToArray());
        var urlEncode = HttpUtility.UrlEncode(base64);
        return string.Concat(idpUri, "?SAMLRequest=", urlEncode);
    }
}

Sospecho que la compresión es de alguna manera la culpa. Estoy usando elDeflaterOutputStream clase deSharpZipLib ¿Qué se supone que debe implementar un algoritmo de desinflado estándar de la industria, así que quizás hay algunas configuraciones aquí que tengo mal?

La salida codificada se puede probar usando esteDepurador SAML2.0 (Es una herramienta de conversión en línea útil). Cuando decodifico mi salida usando esta herramienta, sale como una tontería.

Por lo tanto, la pregunta es: ¿Sabe cómo convertir una cadena SAML en el parámetro de consulta SAMLRequest correctamente desinflado y codificado?

Gracias

EDITAR 1

La respuesta aceptada a continuación da la respuesta al problema. Aquí está el código final corregido por todos los comentarios y respuestas posteriores.

Codificar SAMLRequest - Código de trabajo

private string GenerateSAMLRequestParam()
{
    var saml = string.Format(SAMLRequest, Guid.NewGuid());
    var bytes = Encoding.UTF8.GetBytes(saml);
    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);
    }
}

losSAMLRequest La variable contiene la SAML que se muestra en la parte superior de esta pregunta.

Decodificar SAMLResponse - Código de trabajo

private string DecodeSAMLResponse(string response)
{
    var utf8 = Encoding.UTF8;
    var bytes = utf8.GetBytes(response);
    using (var output = new MemoryStream())
    {
        using (new DeflateStream(output, CompressionMode.Decompress))
        {
            output.Write(bytes, 0, bytes.Length);
        }
        var base64 = utf8.GetString(output.ToArray());
        return utf8.GetString(Convert.FromBase64String(base64));
    }
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta