【发布时间】:2022-03-24 22:07:36
【问题描述】:
我正在尝试将引用添加到我的安全标头并遇到一个相当普遍的错误:
格式错误的引用元素
我已经尝试了以下类似的结果:
- 通过将元素的
ID作为Reference对象的URI传递来引用文档中的元素。 - 通过
LoadXml()方法将XmlElement对象传递给Reference。我正在使用this StackOverflow post 上的重载GetIdElement检索XmlElement引用。
当我将空字符串作为URI 传递时,SignedXml 的ComputeSignature() 方法按预期工作。但是,我最多需要添加 3 个对安全标头的引用。
更新 #1
感谢this blog post,我能够从中创建简化版本,我相信导致我的问题是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();
【问题讨论】:
标签: c# x509certificate xml-signature irs