How to parse a SAML assertion request in .Net

你离开我真会死。 提交于 2019-12-30 06:46:26

问题


I'm trying to implement a SAML SSO solution in .Net, but I'm having a problem parsing the assertion.

I have a sample assertion (looks like byte[] data as text) and corresponding .p7b file.

I want to load the keys from the .p7b and decrypt the assertion to an XML document.

So far I think I'm reading the keys correctly:

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

Then I try to parse the assertion I get a problem:

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

That last statement throws an exception, stating that it can't parse the XML content.

I think this means that I'm missing a step decrypting the assertion - getting the byte[] as text converted to a SAML format XML document.

Anyone know how to add this step? Am I missing something else?


回答1:


I've figured this out - I was missing part of the SAML specification.

The assertion is sent (rather weirdly, since it isn't encrypted) as base64 data, and it was being URL encoded twice as it was sent.

So adding this step gives us a valid assertion:

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

The authentication still isn't working, but I now have valid XML so it's a different problem.



来源:https://stackoverflow.com/questions/6099467/how-to-parse-a-saml-assertion-request-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!