2016-03-01 4 views
4

Я пытаюсь добавить ссылки на мой заголовок безопасности, и я бегу в достаточно общей ошибки:искаженной Базовый элемент

Malformed Reference Element

Я попытался следующие с аналогичными результатами:

  1. REFERENCING элемент в документе, передав в ID элемента как URI объекта Reference.
  2. Передача XmlElement объекта Reference через метод LoadXml(). Я извлекаю ссылку XmlElement с помощью перегруженного GetIdElement, найденного по адресу this StackOverflow post.

Когда я прохожу в пустую строку, как URI, то ComputeSignature() метод из SignedXml работ, как ожидалось. Однако мне нужно добавить до 3 ссылок на заголовок безопасности.

UPDATE # 1
Благодаря this blog post, я был в состоянии создать упрощенную версию из этого, и я считаю, что является причиной моей проблемы является использование Namespace атрибутов и префиксов.

UPDATE # 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

Похоже, по крайней мере, на некоторое время, ответ на получение этой работы следующим образом.

Используйте новый объект SignedXmlWithId, а не используя класс SignedXml, используя класс here.

// 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(); 
Смежные вопросы