升级到java7u25后,XML dig sig错误

时间:2013-06-26 21:58:00

标签: java xml digital-signature

我有一个用于签署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中是否有任何导致此错误的更改?

6 个答案:

答案 0 :(得分:35)

这里的问题相同。由于演变,似乎是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是指关于XML Sig验证的java 7u25演变(请参阅changelog),因此他们必须在工作时 更改其他内容这种演变。

我们通过向javax.xml.crypto.URIDereferencer提供自定义javax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer)来解决此问题,该自定义document.getElementById(...)能够解析尚未存在于DOM文档树中的节点(XMLObject中的片段)。

我现在正在向Oracle报告此问题,我将使用错误ID更新答案。


编辑:apache SVN

中找到了此信息

编辑2:感谢this bug report我明白这是XML“Id”属性处理的演变。

以前版本的java / JSR-105 / SANTUARIO曾对descendant-or-self::*/@Id中使用的“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。

结合使用像Attr这样的小XPath来获取((Element)attr.getOwnerElement()).setIdAttributeNode(attr,true)“Id”节点加上一点Java setIdAttributeXXX()可以让你摆脱困境。

但请注意: clone仅适用于当前文档&节点。如果您adopt / import / setIdAttributeXXX(),您需要在每个DOM树的新节点上执行{{1}}

答案 1 :(得分:10)

我也发现对这个问题的回答很有帮助,但我的解决方案有点不同。我正在使用OpenSAML 2.6.0,并在解析传入文档之前为DocumentBuilderFactory分配模式,通过正确标记ID属性解决了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);

答案 2 :(得分:7)

我的代码遇到了同样的问题:

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

FIX:指定ID

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

答案 3 :(得分:3)

我遇到了同样的问题,并且还跟踪了Cerber提到的代码片段。 我很好奇这是一个错误还是故意改变。

使用此主题中给出的信息 Java XML DOM: how are id Attributes special? 我能够让事情重新恢复工作。

简而言之,'ID'属性必须是'xs:ID'类型(而不是'xs:string'),Dereferencer才能找到它。另请注意,根据您对DocumentBuilderFactory的使用,必须设置XML架构。

答案 4 :(得分:1)

如果你有

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

将其更改为

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

它正在使用java 1.7.0_45

答案 5 :(得分:0)

仅当ID设置为随机UUID [guidForSignature ="_" + UUID.randomUUID().toString();]并且在运行时触发并发请求时(Java 1.8),我才面临同样的问题。

我尝试过如下设置ID属性,这对我没有帮助。但是,将ID属性设置为所有请求的常量ID值可解决问题。

Element element1= doc.getDocumentElement().setIdAttribute("ID", true);

OR

Element e1 =(Element)doc.getElementsByTagName("Assertion").item(0);
e1.setIdAttribute("ID", true);