格式错误的参考元素
Malformed Reference Element
我正在尝试添加对我的安全性的引用 Header 并且 运行 变成了一个相当普遍的错误:
Malformed Reference Element
我尝试了以下类似的结果:
- 通过将元素的
ID
作为 Reference
的 URI
object. 传递来引用文档中的元素
- 通过
LoadXml()
方法将 XmlElement
object 传递给 Reference
。我正在使用 this Whosebug post. 上的重载 GetIdElement
检索 XmlElement
引用
当我将空字符串作为 URI
传递时,SignedXml
的 ComputeSignature()
方法按预期工作。但是,我需要添加最多 3 个对安全 Header.
的引用
更新 #1
感谢 this blog post,我能够从中创建简化版本,我相信导致我的问题的原因是使用了 Namespace
属性和前缀。
更新 #2
<Timestamp>
元素的 Id
属性上的命名空间声明似乎导致了此错误的发生。
更新 #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
class,而是使用 class 详细 here 创建一个新的 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();
我正在尝试添加对我的安全性的引用 Header 并且 运行 变成了一个相当普遍的错误:
Malformed Reference Element
我尝试了以下类似的结果:
- 通过将元素的
ID
作为Reference
的URI
object. 传递来引用文档中的元素
- 通过
LoadXml()
方法将XmlElement
object 传递给Reference
。我正在使用 this Whosebug post. 上的重载
GetIdElement
检索 XmlElement
引用
当我将空字符串作为 URI
传递时,SignedXml
的 ComputeSignature()
方法按预期工作。但是,我需要添加最多 3 个对安全 Header.
更新 #1
感谢 this blog post,我能够从中创建简化版本,我相信导致我的问题的原因是使用了 Namespace
属性和前缀。
更新 #2
<Timestamp>
元素的 Id
属性上的命名空间声明似乎导致了此错误的发生。
更新 #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
class,而是使用 class 详细 here 创建一个新的 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();