我需要创建一个SP使用HTTP重定向绑定方法来发起SAML 2.0身份验证交易。 原来,这是很容易的。 刚刚拿到的IdP URI和串联单查询字符串PARAM SAMLRequest
。 该参数是XML的编码块,描述SAML请求。 到现在为止还挺好。
转换成SAML查询字符串PARAM时,问题就来了。 我相信,准备的过程应该是:
- 建立一个SAML字符串
- 压缩此字符串
- Base64编码字符串
- URLEncode的字符串。
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>
代码
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);
}
}
我怀疑压缩在某种程度上难辞其咎。 我现在用的是DeflaterOutputStream
从类SharpZipLib这是应该这样也许有一些设置,在这里我有错实施的行业标准放气的算法?
编码的输出可以使用该被测试SAML2.0调试器 (它的一个有用的在线转换工具)。 当我解码使用这个工具我的输出它出来无稽之谈。
因此,问题是:你知不知道如何将SAML字符串转换成正确的放气和编码SAMLRequest查询PARAM?
谢谢
编辑1
下面的接受的答案给出答案的问题。 这里是由所有后续意见和答案修正的最终代码。
编码SAMLRequest -工作守则
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);
}
}
所述SAMLRequest
变量包含在这个问题的顶部示出的SAML。
解码SAMLResponse -工作守则
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));
}
}