Wie bereite ich eine 'HTTP Redirect Binding'-SAML-Anfrage mit C # korrekt vor?

Ich muss eine SP-initiierte SAML 2.0-Authentifizierungstransaktion mithilfe der HTTP-Redirect-Bindungsmethode erstellen. Es stellt sich heraus, dass dies ziemlich einfach ist. Rufen Sie einfach den IdP-URI ab und verknüpfen Sie einen einzelnen Abfragezeichenfolge-ParameterSAMLRequest. Der Parameter ist ein codierter XML-Block, der die SAML-Anforderung beschreibt. So weit, ist es gut.

Das Problem tritt beim Konvertieren der SAML in den Abfragezeichenfolge-Parameter auf. Ich glaube, dieser Vorbereitungsprozess sollte sein:

Erstellen Sie eine SAML-ZeichenfolgeKomprimiere diese SaiteBase64 kodiert den StringUrlEncode die Zeichenfolge.

Die SAML-Anfrage

<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>

Der Code

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);
    }
}

Ich vermute, die Komprimierung ist irgendwie schuld. Ich benutze dieDeflaterOutputStream Klasse vonSharpZipLib Was soll einen Industriestandard-Deflate-Algorithmus implementieren? Vielleicht gibt es hier einige Einstellungen, die ich falsch gemacht habe.

Damit kann die codierte Ausgabe getestet werdenSAML2.0 Debugger (Es ist ein nützliches Online-Konvertierungs-Tool). Wenn ich meine Ausgabe mit diesem Tool dekodiere, kommt es als Unsinn heraus.

Die Frage lautet daher: Wissen Sie, wie eine SAML-Zeichenfolge in den korrekt deflationierten und codierten SAMLRequest-Abfrageparameter konvertiert wird?

Vielen Dank

EDIT 1

Die unten akzeptierte Antwort gibt die Antwort auf das Problem. Hier ist der endgültige Code, der durch alle nachfolgenden Kommentare und Antworten korrigiert wird.

Kodieren Sie SAMLRequest - Working Code

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);
    }
}

DasSAMLRequest Die Variable enthält die SAML, die oben in dieser Frage angezeigt wird.

Dekodiere SAMLResponse - Arbeitscode

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));
    }
}

Antworten auf die Frage(2)

Ihre Antwort auf die Frage