«Неправильный элемент ссылки» при добавлении ссылки на основе атрибута Id с классом SignedXml - PullRequest
17 голосов
/ 24 февраля 2011

Невозможно подписать элемент с помощью атрибута Id при наличии префикса пространства имен:

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() потерпит неудачу здесь с 'Malformed Reference Element', как это должно быть сделано?

Ответы [ 4 ]

36 голосов
/ 24 июня 2011

Мы использовали подход к созданию подкласса System.Security.Cryptography.Xml.SignedXml класса ...

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;
    }
}
2 голосов
/ 03 марта 2016

Следует отметить, что вам нужно будет использовать объект SignedXmlWithId вместо SignedXml, чтобы иметь возможность использовать переопределенный метод GetIdElement(). Как только я это сделал, я смог подписать XmlElement и обойти ошибку Неправильный элемент ссылки .

Смотрите мой пост на эту тему здесь .

2 голосов
/ 24 февраля 2011

var reference = new Reference (""); // Это подпишет весь документ

0 голосов
/ 25 марта 2011

SignedXml не распознает u: Id в качестве действительного идентификатора XML, а для подписи XML требуется, чтобы он был идентификатором XML.

Вы можете использовать схему (http://docs.oasis -open.org /wss / 2004/01 / oasis-200401-wss-wssecurity-utility-1.0.xsd, если вы пытаетесь использовать идентификатор WS-Security), или добавьте DTD к фрагменту XML.(]> для фрагмента XML).Добавление DTD только к вашему LoadXml заставит SignedXml распознавать Id, но, поскольку SOAP не допускает DTD, не включайте DTD в свой SOAP на проводе.

...