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