Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pull SecurityToken from SAML Assertion

Tags:

c#

saml

I have the XML of a SAML Assertion that looks like this:

<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_9b6e6302-d6a8-47f0-9155-1051a05edbfb" Issuer="http://example.com/adfs/services/trust" IssueInstant="2013-04-29T19:35:51.197Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
...
</saml:Assertion>

I am trying to get a SecurityToken out of this XML using code similar to the following:

// Loading the XML referenced above.
XDocument doc = XDocument.Load(new StringReader(assertion));

// Creating config to use in TokenHandlers below; required if not using a SecurityTokenHandlerCollection.
SecurityTokenHandlerConfiguration config = new SecurityTokenHandlerConfiguration();
config.AudienceRestriction.AllowedAudienceUris.Add(new Uri("https://localhost/Orchard/"));
config.CertificateValidator = X509CertificateValidator.None;

// Both of these lines throw Exceptions, as explained below.
new Saml11SecurityTokenHandler() { Configuration = config }.ReadToken(doc.CreateReader());
new Saml2SecurityTokenHandler() { Configuration = config }.ReadToken(doc.CreateReader());

If I try to read the token using the Saml11SecurityTokenHandler, I get the following Exception:

ID4075: SAML Assertion is missing the required 'MajorVersion' Attribute.

If I try to read the token using the Saml2SecurityTokenHandler, I get a different Exception:

Element 'Assertion' with namespace name 'urn:oasis:names:tc:SAML:2.0:assertion' was not found.

Obviously the one for Saml2SecurityTokenHandler makes sense, since this is a SAML 1.1 Assertion. However, why can't the SAML 1.1 TokenHandler read this Assertion?

EDIT: The reader appears to be empty; why is that? doc has content.

string notEmpty = doc.FirstNode.ToString();
string empty = doc.CreateReader().ReadOuterXml();
like image 480
zimdanen Avatar asked Mar 25 '23 03:03

zimdanen


1 Answers

Drawing from the technique shown here, this works:

SecurityToken token;
using (StringReader sr = new StringReader(assertion))
{
    using (XmlReader reader = XmlReader.Create(sr))
    {
        if (!reader.ReadToFollowing("saml:Assertion"))
        {
            throw new Exception("Assertion not found!");
        }
        SecurityTokenHandlerCollection collection = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
        token = collection.ReadToken(reader.ReadSubtree());
    }
}

Make sure you don't change of the whitespace in the XML document, otherwise you'll get a signature verification error.

like image 129
zimdanen Avatar answered Apr 04 '23 18:04

zimdanen