2011-02-24 45 views
14

No se puede acceder elemento de atributo Id cuando hay un prefijo de espacio de nombres:'Elemento de referencia de formato incorrecto' al agregar una referencia basada en un atributo de la identificación con la clase SignedXml

void Main() 
{ 
    var doc = new XmlDocument(); 
    doc.LoadXml("<root xmlns:u=\"myuri\"><test u:Id=\"_0\">Zebra</test></root>"); 

    SignedXml signedXml = new SignedXml(doc); 
    signedXml.SigningKey = new RSACryptoServiceProvider(); 

    Reference reference = new Reference("#_0"); 
    signedXml.AddReference(reference); 

    signedXml.ComputeSignature(); 
} 

ComputeSignature() fallará aquí con 'Elemento de referencia malformados' ¿Cómo debe hacerse esto?

Respuesta

31

El enfoque que utilizamos fue subclase System.Security.Cryptography.Xml.SignedXml clase ...

public class SignedXmlWithId : SignedXml 
{ 
    public SignedXmlWithId(XmlDocument xml) : base(xml) 
    { 
    } 

    public SignedXmlWithId(XmlElement xmlElement) 
     : base(xmlElement) 
    {  
    } 

    public override XmlElement GetIdElement(XmlDocument doc, string id) 
    { 
     // check to see if it's a standard ID reference 
     XmlElement idElem = base.GetIdElement(doc, id); 

     if (idElem == null) 
     { 
      XmlNamespaceManager nsManager = new XmlNamespaceManager(doc.NameTable); 
      nsManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"); 

      idElem = doc.SelectSingleNode("//*[@wsu:Id=\"" + id + "\"]", nsManager) as XmlElement; 
     } 

     return idElem; 
    } 
} 
+1

Eres mi héroe por hoy. Gracias. – Bon

+1

Tuve el mismo error, pero el problema fue que el valor de SecurePart \ Id comenzó con el número (solo se permiten caracteres). –

+1

@ JanFriedrich debe publicar una respuesta de trabajo, lo acepto si eso es correcto. –

3

var referencia = nueva Referencia (""); // Esto firmará el documento completo

+1

Pero necesito proporcionar la identificación del elemento para firmar ... el xml real es una envoltura de jabón y el uso de ID parece ser la forma en que se hace. –

+0

ok, el xml tiene el atributo "u: Id", si lo cambia a " ...", entonces ComputeSignature debería funcionar. Si no puede cambiar la entrada, tendrá que utilizar una referencia "#xpointer". –

0

SignedXml no reconoce u: Id como una identificación XML válida, y la firma XML requiere que sea una identificación XML.

Puede usar el esquema (http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd si está tratando de usar un WS- ID de seguridad) o agregue una DTD al fragmento XML. (]> para un fragmento XML). Agregar una DTD a solo su LoadXml hará que SignedXml reconozca la Id, pero como SOAP no permite las DTD, no incluya la DTD en su SOAP on-the-wire.

2

Debe tenerse en cuenta que tendrá que utilizar SignedXmlWithId objeto en lugar de SignedXml objeto con el fin de poder utilizar el método anulado GetIdElement() . Una vez que lo hice, pude firmar un XmlElement y solucionar el error Elemento de referencia mal formado.

See my post about this topic here.

+0

buen trabajo tiene alguna rep ... :) –

Cuestiones relacionadas