格式错误的参考元素

本文关键字:元素 参考 错误 格式 | 更新日期: 2023-09-27 18:37:06

我正在尝试将引用添加到我的安全标头,但遇到了一个相当普遍的错误:

格式错误的参考元素

我尝试了以下方法,结果相似:

  1. 通过将元素的ID作为Reference对象的URI传递来引用文档中的元素。
  2. 通过 LoadXml() 方法将XmlElement对象传递给Reference。 我正在使用在此 StackOverflow 帖子中找到的重载GetIdElement来检索XmlElement引用。

当我传入一个空字符串作为URI时,SignedXmlComputeSignature()方法按预期工作。 但是,我需要向安全标头添加最多 3 个引用。

更新 #1
多亏了这篇博文,我才能从中创建简化版本,我相信导致我问题的原因是使用了Namespace属性和前缀。

更新 #2
看起来好像 <Timestamp> 元素的 Id 属性上的命名空间声明导致发生此错误。

更新 #3
我想我得到了这个工作。 请参阅下面的回答帖子。

工作示例:
请注意,定义了命名空间的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 类,

而是使用此处详述的类创建新的 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();