如何在.Net中解析SAML断言请求

如何在.Net中解析SAML断言请求,.net,single-sign-on,x509certificate,saml,pkcs#7,.net,Single Sign On,X509certificate,Saml,Pkcs#7,我试图在.Net中实现SAML SSO解决方案,但在解析断言时遇到问题 我有一个示例断言(看起来像byte[]数据作为文本)和相应的.p7b文件 我想从.p7b加载密钥,并将断言解密为XML文档 到目前为止,我认为我正确地阅读了钥匙: // get the key data byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b"); // decode the keys var cms = new SignedCms(

我试图在.Net中实现SAML SSO解决方案,但在解析断言时遇到问题

我有一个示例断言(看起来像
byte[]
数据作为文本)和相应的
.p7b
文件

我想从
.p7b
加载密钥,并将断言解密为XML文档

到目前为止,我认为我正确地阅读了钥匙:

// get the key data
byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b");

// decode the keys
var cms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber);
cms.Decode(certificateData);

var samlCertificates = cms.Certificates;
然后,我尝试分析断言,我遇到了一个问题:

// we have a keychain of X509Certificate2s, we need a collection of tokens
var certificatesAsTokens =
    from X509Certificate2 cert in samlCertificates
    select new X509SecurityToken(cert) as SecurityToken;

// get a token resolver
var tokens = new ReadOnlyCollection<SecurityToken>(
    certificatesAsTokens.ToList());
var resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
    tokens, true);

// get the SAML data in an XML reader
var reader = XmlReader.Create(assertionPostStream);

// use the WS Security stuff to parse the reader
var securityToken = WSSecurityTokenSerializer.
    DefaultInstance.ReadToken(reader, resolver) as SamlSecurityToken;
//我们有一个X509Certificate2的密钥链,我们需要一组令牌
斯托克斯=
来自X509Certificate2相同证书中的证书
选择新的X509SecurityToken(cert)作为SecurityToken;
//获取令牌解析器
var tokens=new ReadOnlyCollection(
证书stokens.ToList());
var resolver=SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
代币,真实);
//在XML读取器中获取SAML数据
var reader=XmlReader.Create(断言PostStream);
//使用WS-Security来解析读取器
var securityToken=WSSecurityTokenSerializer。
ReadToken(读取器、解析器)作为SamlSecurityToken;
最后一条语句抛出一个异常,说明它无法解析XML内容

我认为这意味着我错过了解密断言的一个步骤——将
字节[]
作为文本转换为SAML格式的XML文档


有人知道如何添加此步骤吗?我还遗漏了什么吗?

我已经弄明白了——我遗漏了SAML规范的一部分

断言作为base64数据发送(相当奇怪,因为它没有加密),并且它被URL编码了两次

因此,添加此步骤为我们提供了一个有效的断言:

// spec says "SAMLResponse=" 
string rawSamlData = Request["SAMLResponse"];

// the sample data sent us may be already encoded, 
// which results in double encoding
if (rawSamlData.Contains('%'))
{
    rawSamlData = HttpUtility.UrlDecode(rawSamlData);
}

// read the base64 encoded bytes
byte[] samlData = Convert.FromBase64String(rawSamlData);

// read back into a UTF string
string samlAssertion = Encoding.UTF8.GetString(samlData);

是的,但我现在有了有效的XML,所以这是一个不同的问题。

感谢您发布了它的工作原理。这帮我节省了很多时间。