'Malformed Reference Element' when adding a reference based on an Id attribute with SignedXml class
21,168
Solution 1
The approach we used was to subclass System.Security.Cryptography.Xml.SignedXml
class...
public class SignedXmlWithId : SignedXml
{
public SignedXmlWithId(XmlDocument xml) : base(xml)
{
}
public SignedXmlWithId(XmlElement xmlElement)
: base(xmlElement)
{
}
public override XmlElement GetIdElement(XmlDocument doc, string id)
{
// check to see if it's a standard ID reference
XmlElement idElem = base.GetIdElement(doc, id);
if (idElem == null)
{
XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement;
}
return idElem;
}
}
Solution 2
var reference = new Reference(""); // This will sign the entire document
Solution 3
It should be noted that you will need to use SignedXmlWithId
object instead of SignedXml
object in order to be able to use the overridden GetIdElement()
method. Once I did that, I was able to sign an XmlElement
and get around the Malformed Reference Element error.
See my post about this topic here.
Related videos on Youtube
Author by
Dog Ears
Updated on March 03, 2020Comments
-
Dog Ears about 4 years
Unable to sign element by Id attribute when there's a namespace prefix:
void Main() { var doc = new XmlDocument(); doc.LoadXml("<root xmlns:u=\"myuri\"><test u:Id=\"_0\">Zebra</test></root>"); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = new RSACryptoServiceProvider(); Reference reference = new Reference("#_0"); signedXml.AddReference(reference); signedXml.ComputeSignature(); }
ComputeSignature()
will fail here with 'Malformed Reference Element' how should this be done? -
Dog Ears about 13 yearsBut I need to supply the id of the element to sign..the actual xml is a soap envelope and using Ids seems to be the way that it's done.
-
Richard Schneider about 13 yearsok, the xml has atttibute "u:Id", if you change it to "<test Id='0'>...", then ComputeSignature should work. If you can not change the input then you will have use a "#xpointer" reference.
-
Bon over 8 yearsYou are my hero for today. Thank you.
-
Jan Friedrich about 8 yearsI had the same error, but the problem was that the value for SecurePart\Id started with number (only characters are allowed).
-
Dog Ears about 8 years@JanFriedrich you should post a working answer, I'll willing accept that if correct.
-
Michael Ritchson over 4 years@JanFriedrich, that was my issue as well. I was working with an ID for a SAML request. Had to conform to the XML ID convention. See w3.org/TR/xml-id which is an NCNAME w3.org/TR/xml-names11/#NT-NCName, which the starting character is restricted. I used a GUID with no braces, just prepended it with an _ for the ID.