2011-05-23 126 views
5

我试图在.Net中实现SAML SSO解决方案,但解析断言时出现问题。如何解析.Net中的SAML断言请求

我有一个示例断言(看起来像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; 

这最后一条语句抛出一个异常,说明它无法分析XML内容。

我认为这意味着我错过了解密断言的步骤 - 获取byte[]作为文本转换为SAML格式的XML文档。

任何人都知道如何添加此步骤?我错过了别的吗?

回答

12

我已经想通了 - 我缺少部分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); 

authentication still isn't working,但是我现在有有效的XML所以这是一个不同的问题。

+2

感谢张贴你如何工作。它为我节省了很多时间。 – 2013-09-06 12:38:08