2

I am trying to build a SAML Assertion in C# for a web service i am trying to connect to. I am using SamlAssertion and X509 Cert as SigningCredentials

This generates a SamlSecurityToken, i then serialize. When i try to validate the signature i get a error message saying the

Malformed reference element.

Code to Serialize

        var result = new StringBuilder();
        using (var writer = XmlWriter.Create(result))
        {
            var serializer = new WSSecurityTokenSerializer(SecurityVersion.WSSecurity11, true);
            serializer.WriteToken(writer, obj); //Obj is the SamlSecurityToken
        }

        var xml = result.ToString();

Signature generated:

<Signature 
    xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
        <Reference URI="#_caeceed6-7006-4354-a398-75a8e4c52818">
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></Transform>
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
            <DigestValue>SOME VALUE</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>SOME VALUE</SignatureValue>
</Signature>

This is almost as the example i got from the web service provider. Part of the example:

<ds:Transforms>
    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform>
    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
    <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="code ds kind rw saml samlp typens #default xsd xsi"></ec:InclusiveNamespaces>
</ds:Transform>

The example and the generated XML looks almost the same, except some prefixes and the InclusiveNamespaces tag.

I have also seen examples where people use SignedXml instead of the WSSecurityTokenSerializer, why is that? more control over the generated XML? Or can i not use the WSSecurityTokenSerializer to create the token?

Lasse Vabe Rolstad
  • 602
  • 2
  • 9
  • 20
  • It's hard to tell without seeing the whole generated message and stack trace. But maybe it has something to do with the prefix thingies? As in http://stackoverflow.com/questions/5099156/malformed-reference-element-when-adding-a-reference-based-on-an-id-attribute-w – Thuan Nov 22 '16 at 03:01
  • 1
    By overriding the GetIdElement i was able to validate the signature – Lasse Vabe Rolstad Nov 22 '16 at 12:03

1 Answers1

1

I created a class based on the example posted by Thuan to return the correct element, i had to overrid the SignedXml class with a custom search for AssertionID to return the correct element to validate.

public class SignedSamlXml : SignedXml
{
    public SignedSamlXml()
    {
    }

    public SignedSamlXml(XmlDocument doc)
        : base(doc)
    {
    }

    public override XmlElement GetIdElement(XmlDocument document, string idValue)
    {
        var idElement = base.GetIdElement(document, idValue);
        if (idElement == null)
        {
            var attributes = document.SelectNodes("//@AssertionID");
            if (attributes == null) return null;

            foreach (XmlAttribute attr in attributes)
            {
                if (attr.Value == idValue)
                {
                    return attr.OwnerElement;
                }
            }
        }

        return idElement;
    }
}
Lasse Vabe Rolstad
  • 602
  • 2
  • 9
  • 20