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 を参照))を参照しているため、 壊れたこの進化に取り組んでいる間に何か他のものを変更しました。
DOMドキュメントツリー(XMLObjectのフラグメント)にまだ含まれていないノードを解決できるカスタム_javax.xml.crypto.URIDereferencer
_をjavax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer)
に提供することで、この問題を回避しました。
これを現在Oracleに報告しています。バグIDで回答を更新します。
EDIT:これは Apache SVN で見つかりました
編集2:このバグレポートのおかげで これはXMLの進化であると理解しました "Id "属性の処理。
以前のバージョンのJava/JSR-105/SANTUARIOは、document.getElementById(...)
で使用される「Id」属性に対して非常に寛容でしたが、この新しいバージョンでは、[として識別される属性が必要です。 〜#〜] id [〜#〜]XMLスピーキング。つまり、属性に「Id」または「ID」という名前を付けるだけでは不十分であり、最終的にXSD/DTDスキーマ検証によってIDとしてマークする必要があります。
残念ながら、私は無効なスキーマをフォローしているため、Javaで解析できません。
同じ状況の場合は、以下の私の解決策を参照してください。それ以外の場合、XMLドキュメントに有効なスキーマがある場合は、@ sherbソリューション https://stackoverflow.com/a/17437919/233906 をご覧ください。
さいわい、 Element.setIdAttributeNode(org.w3c.dom.Attr,boolean)
のようなメソッドを使用して、IDとして属性をtagできます。
_descendant-or-self::*/@Id
_のような小さなXPathと組み合わせて、Attr
"Id"ノードと少しのJava _((Element)attr.getOwnerElement()).setIdAttributeNode(attr,true)
_をフェッチすると、問題が解決します。
ただし、注意してください:setIdAttributeXXX()
は、現在のドキュメントとノードに対してのみ有効です。 clone
/adopt
/import
の場合、各DOMツリーの新しいノードでsetIdAttributeXXX()
を実行する必要があります
また、この質問に対する回答は非常に役に立ちましたが、私の解決策は少し異なりました。私はOpenSAML2.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);
私はコードで同じ問題を抱えていました:
element.setAttributeNS(null, "Id", elementID);
FIX: idを指定
element.setAttributeNS(null, "Id", elementID);
Attr idAttr = element.getAttributeNode("Id");
element.setIdAttributeNode(idAttr, true);
私は同じ問題に直面し、Cerberによって言及されたコードスニペットまで追跡しました。これがバグなのか、意図的に行われた変更なのか知りたいです。
このスレッドで提供される情報 Java XML DOM:id属性はどのように特別なものですか? 私は物事を再び機能させることができました。
簡単に言うと、間接参照がそれを見つけるには、「ID」属性は「xs:ID」タイプである必要があります(たとえば、「xs:string」ではありません)。また、DocumentBuilderFactoryの使用に応じて、XMLスキーマを設定する必要があることにも注意してください。
あなたが持っている場合
dsObjectChild.setAttribute("Id", "My-id-value");
に変更
dsObjectChild.setAttribute("Id", "My-id-value");
dsObjectChild.setIdAttribute("Id", true);
Java 1.7.0_45
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);