格式错误的参考元素
我试图将引用添加到我的安全标头,并遇到一个相当普遍的错误:
格式错误的参考元素
我尝试了以下类似的结果:
- 通过将元素的
ID
作为Reference
对象的URI
传入来引用文档中的元素。 - 通过
LoadXml()
方法将XmlElement
对象传递给Reference
。 我正在使用此StackOverflowpost上找到的重载GetIdElement
检索XmlElement
引用。
当我传入一个空字符串作为URI
, ComputeSignature()
方法按预期工作。 但是,我需要添加最多3个对安全标头的引用。
更新#1
感谢这篇博文 ,我能够从中创建简化版本,我相信导致我的问题的是使用Namespace
属性和前缀。
更新#2
看起来似乎元素的
Id
属性上的Namespace声明导致发生此错误。
更新#3
我想我有这个工作。 请参阅下面的回答post。
工作样本:
请注意,定义了命名空间的Id XAttribute
不起作用; 而没有定义命名空间的Id XAttribute
确实有效。
private void CreateSecurityAndTimestampXML(string fileName) { TimestampID = "TS-E" + GUID.NewGuid(); DateTime SecurityTimestampUTC = DateTime.UtcNow; XDocument xdoc = new XDocument( new XElement(wsse + "Security", new XAttribute(XNamespace.Xmlns + "wsse", wsse.NamespaceName), new XAttribute(XNamespace.Xmlns + "wsu", wsu.NamespaceName), new XElement(wsu + "Timestamp", // new XAttribute(wsu + "Id", TimestampID), // <-- Does Not Work new XAttribute("Id", TimestampID), // <-- Works new XElement(wsu + "Created", SecurityTimestampUTC.ToString(_timestampFormat)), new XElement(wsu + "Expires", SecurityTimestampUTC.AddMinutes(10).ToString(_timestampFormat)) ) ) ); using (XmlTextWriter tw = new XmlTextWriter(fileName, new UTF8Encoding(false))) { xdoc.WriteTo(tw); } } // Snippet string[] elements = { TimestampID }; foreach (string s in elements) { Reference reference = new Reference() { Uri = "#" + s }; XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform(); env.InclusiveNamespacesPrefixList = _includedPrefixList; reference.AddTransform(env); xSigned.AddReference(reference); } // Add Key Info Here. // Compute the Signature. xSigned.ComputeSignature();
看起来,至少在目前,实现这项工作的答案如下。
而不是使用SignedXml
类,使用SignedXml
类创建一个新的SignedXmlWithId
对象。
// Create a new XML Document. XmlDocument xdoc = new XmlDocument(); xdoc.PreserveWhitespace = true; // Load the passed XML File using its name. xdoc.Load(new XmlTextReader(fileName)); // Create a SignedXml Object. //SignedXml xSigned = new SignedXml(xdoc); SignedXmlWithId xSigned = new SignedXmlWithId(xdoc); // Use this class instead of the SignedXml class above. // Add the key to the SignedXml document. xSigned.SigningKey = cert.PrivateKey; xSigned.Signature.Id = SignatureID; xSigned.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NWithCommentsTransformUrl; //Initialize a variable to contain the ID of the Timestamp element. string elementId = TimestampID; Reference reference = new Reference() { Uri = "#" + elementId }; XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform(); env.InclusiveNamespacesPrefixList = _includedPrefixList; reference.AddTransform(env); xSigned.AddReference(reference); // Add Key Information (omitted) // Compute Signature xSigned.ComputeSignature();