Подтвердить что ты не робот

Ошибка XML dig sig после обновления до java7u25

У меня есть приложение Java для подписи документов XML. После обновления Java до последней версии (Java7u25) он перестает работать. Я получаю следующую ошибку:

javax.xml.crypto.dsig.XMLSignatureException:
javax.xml.crypto.URIReferenceException: 
com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException:
Cannot resolve element with ID ...

Возврат к java7u21 решает проблему. Есть ли какие-либо изменения в XML Dig Sig API, которые вызывают эту ошибку?

4b9b3361

Ответ 1

Такая же проблема. Кажется, это ошибка в JVM из-за эволюции.

Я отправил его на com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment

В java 7u21 и до:

91: // Element selectedElem = doc.getElementById(id);
92: selectedElem = IdResolver.getElementById(doc, id);

В java 7u25:

87: selectedElem = doc.getElementById(id);
    //...
93: if (secureValidation) {

secureValidation относится к эволюции java 7u25 при проверке XML Sig (см. журнал изменений), поэтому они должны иметь broken изменил что-то еще во время работы над этой эволюцией.

Мы работали над этой проблемой, предоставив пользовательский javax.xml.crypto.URIDereferencer to javax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer), который может разрешить node, которые еще не находятся в дереве документов DOM (фрагменты в XMLObject).

Я сообщаю об этом Oracle прямо сейчас, я обновлю ответ с идентификатором ошибки.


EDIT: нашел это в apache SVN


Изменить 2: Благодаря этот отчет об ошибке Я понял, что это была эволюция в XML "Id" .

Предыдущие версии java/JSR-105/SANTUARIO были очень терпимыми к атрибутам "Id", используемым в document.getElementById(...), но для этой новой версии требуется атрибут, который обозначается как ID. Я имею в виду, что присвоение имени "Id" или "ID" больше не является достаточным, вам нужно, чтобы он был помечен как идентификатор, в конечном итоге с помощью проверки схемы XSD/DTD.

Несчастливо, я следую схеме, которая недействительна и поэтому не обрабатывается Java.

Если вы находитесь в той же ситуации, см. мое решение ниже. В противном случае, если у вас есть документ XML, есть действительная схема, посмотрите на решение @sherb fooobar.com/questions/261775/...

Решение

К счастью, вы можете пометить атрибут как идентификатор, используя методы, такие как Element.setIdAttributeNode(org.w3c.dom.Attr,boolean).

Объединяясь с небольшим XPath, как descendant-or-self::*/@Id, чтобы извлечь Attr "Идентификационные" узлы плюс небольшая Java ((Element)attr.getOwnerElement()).setIdAttributeNode(attr,true), вы должны избавиться от проблем.

Но будьте осторожны: setIdAttributeXXX() действителен только для текущего документа и node. Если вы clone/adopt/import, вам нужно сделать setIdAttributeXXX() в новых узлах каждого дерева DOM

Ответ 2

Я также нашел ответы на этот вопрос весьма полезными, но мое решение было немного иным. Я работаю с OpenSAML 2.6.0 и назначая схему DocumentBuilderFactory непосредственно перед разбором входящего документа, разрешающего исключение ResourceResolverException: Cannot resolve element with ID..., правильно маркируя атрибуты идентификатора. Вот пример:

InputStream in = new ByteArrayInputStream(assertion.getBytes());       
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new URL("http://docs.oasis-open.org/security/saml/v2.0/saml-schema-protocol-2.0.xsd"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setSchema(schema);
Document document = factory.newDocumentBuilder().parse(in);

Ответ 3

У меня была такая же проблема с кодом:

element.setAttributeNS(null, "Id", elementID);

ИСПРАВЛЕНИЕ: укажите id

element.setAttributeNS(null, "Id", elementID);
Attr idAttr = element.getAttributeNode("Id");
element.setIdAttributeNode(idAttr, true);

Ответ 4

i столкнулся с той же проблемой, а также отследил ее до фрагментов кода, упомянутых Cerber. Мне интересно, это ошибка или изменение сделано специально.

С информацией, приведенной в этой теме Java XML DOM: как особые атрибуты атрибута? я снова смог вернуть работу.

В двух словах атрибут "ID" должен иметь тип "xs: ID" (а не, например, "xs: string" ) для Dereferencer, чтобы найти его. Также обратите внимание, что в зависимости от использования DocumentBuilderFactory должна быть установлена ​​XML-схема.

Ответ 5

Если у вас

dsObjectChild.setAttribute("Id", "My-id-value");

Измените его на

dsObjectChild.setAttribute("Id", "My-id-value");
dsObjectChild.setIdAttribute("Id", true);

Работает с java 1.7.0_45