我有一个用于签署 XML 文档的 Java 应用程序。将 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 是否有任何更改?
最佳答案
同样的问题。由于进化,似乎是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 验证上的演变(参见 changelog ),因此他们必须在工作时 broken 更改其他内容关于这一演变。
我们通过向 javax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer)
提供自定义 javax.xml.crypto.URIDereferencer
解决了这个问题它能够解析尚未在 DOM 文档树中的节点(XMLObject 中的片段)。
我现在正在向 Oracle 报告此问题,我将使用错误 ID 更新答案。
编辑:在 apache SVN 中找到了这个
编辑 2: 感谢 this bug report我知道这是 XML“Id”属性处理的演变。
以前版本的 java/JSR-105/SANTUARIO 过去对 document.getElementById(...)
中使用的“Id”属性非常宽容,但这个新版本需要一个已识别的属性作为 ID XML 说话。我的意思是,将属性命名为“Id”或“ID”已经不够用了,您需要将其标记为 ID,最终通过 XSD/DTD 架构验证。
很遗憾,我使用的架构无效,因此 Java 无法解析。
如果您处于相同情况,请参阅下面的解决方案。否则,如果您的 XML 文档确实具有有效架构,请查看@sherb 解决方案 https://stackoverflow.com/a/17437919/233906
解决方案
幸运的是,您可以使用 Element.setIdAttributeNode(org.w3c.dom.Attr,boolean)
等方法将属性标记为 ID。 .
结合像 descendant-or-self::*/@Id
这样的小 XPath 来获取 Attr
"Id"节点以及小 Java (( Element)attr.getOwnerElement()).setIdAttributeNode(attr,true)
应该能让你摆脱困境。
但要小心: setIdAttributeXXX()
仅对当前文档和节点有效。如果你 clone
/adopt
/import
你需要在每个 DOM 的新节点上做一个 setIdAttributeXXX()
树
关于java - 升级到 java7u25 后 XML dig sig 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17331187/