2016-03-01 118 views
4

我試圖引用添加到我的安全頁眉和正在運行到一個非常通用的錯誤:畸形的參考元素

Malformed Reference Element

我曾嘗試與類似的結果如下:

  1. 引用元素在文檔中通過傳入ID的元素作爲Reference對象的URI
  2. 通過LoadXml()方法將XmlElement對象傳遞給Reference。我通過使用this StackOverflow post上發現的超載GetIdElement檢索XmlElement參考。

當我在一個空字符串傳遞作爲URI,如預期的那樣SignedXml作品ComputeSignature()方法。但是,我需要添加最多3個對安全標題的引用。

更新#1
感謝this blog post,我能夠創造從簡化版本,我認爲是什麼原因造成我的問題是使用Namespace屬性和前綴。

更新#2
看來好像在<Timestamp>元件的Id屬性的命名空間聲明,導致發生該錯誤。

UPDATE#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(); 

回答

5

看起來,至少從目前來看,答案得到這個工作如下。

而不是使用SignedXml類,使用類詳細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();