22

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 の変更はありますか?

4

6 に答える 6

39

ここでも同じ問題。進化による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を参照) を参照しているため、この進化に取り組んでいる間に何か他のものを壊した に違いありません。

DOM ドキュメント ツリー (XMLObject のフラグメント) にまだ存在しないノードを解決できるカスタムjavax.xml.crypto.URIDereferencerを提供することで、この問題を回避しました。javax.xml.crypto.dom.DOMCryptoContext.setURIDereferencer(URIDereferencer)

現在、これを Oracle に報告しています。回答をバグ ID で更新します。


編集:Apache SVNでこれを見つけました


編集 2:このバグ レポートのおかげで、これは XML の "Id" 属性処理の進化であることがわかりました。

以前のバージョンの java/JSR-105/SANTUARIO は、使用される「Id」属性に対して非常に寛容でしたdocument.getElementById(...)が、この新しいバージョンでは、XML を話すIDとして識別される属性が必要です。つまり、属性に「Id」または「ID」という名前を付けるだけでは不十分です。最終的には XSD/DTD スキーマ検証によって、ID としてマークする必要があります。

残念ながら、有効ではないため Java で解析できないスキーマに従っています。

同じ状況にある場合は、以下の私の解決策を参照してください。それ以外の場合、XML ドキュメントに有効なスキーマがある場合は、@sherb ソリューションhttps://stackoverflow.com/a/17437919/233906をご覧ください。

解決

幸いなことに、のようなメソッドを使用して属性を ID としてタグ付けElement.setIdAttributeNode(org.w3c.dom.Attr,boolean)できます。

「Id」ノードdescendant-or-self::*/@Idを取得するような小さな XPath と、小さな Java を組み合わせることで、問題を解決できます。Attr((Element)attr.getOwnerElement()).setIdAttributeNode(attr,true)

ただし、注意してください: setIdAttributeXXX()現在のドキュメントとノードに対してのみ有効です。//各 DOM ツリーの新しいノードで //cloneを実行する必要がある場合adoptimportsetIdAttributeXXX()

于 2013-06-27T15:41:25.093 に答える
10

この質問への回答も非常に役に立ちましたが、私の解決策は少し異なりました。私は OpenSAML 2.6.0 を使用しており、受信ドキュメントを解析する直前に DocumentBuilderFactory にスキーマを割り当てるとResourceResolverException: Cannot resolve element with ID...、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);
于 2013-07-03T00:31:03.007 に答える
8

私はコードに同じ問題を抱えていました:

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

FIX : ID を指定

element.setAttributeNS(null, "Id", elementID);
Attr idAttr = element.getAttributeNode("Id");
element.setIdAttributeNode(idAttr, true);
于 2013-09-11T15:30:58.950 に答える
3

私は同じ問題に直面し、Cerber が言及したコード スニペットまで追跡しました。これがバグなのか、意図的に変更されたのか、気になります。

このスレッド Java XML DOM: id 属性はどのように特別なのですか? 私は物事を再び仕事に戻すことができました。

簡単に言うと、Dereferencer がそれを見つけるためには、'ID' 属性がタイプ 'xs:ID' でなければなりません (例えば 'xs:string' ではありません)。また、DocumentBuilderFactory の使用に応じて、XML スキーマを設定する必要があることに注意してください。

于 2013-06-28T12:49:31.043 に答える
2

あなたが持っている場合

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

に変更します

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

Java 1.7.0_45で動作しています

于 2014-04-01T22:53:37.927 に答える
0

guidForSignature ="_" + UUID.randomUUID().toString();ID がランダムな UUID [ ] で設定されている場合と、実行時にトリガーされる同時要求がある場合 (Java 1.8) にのみ、同じ問題に直面しています。

以下のようにID属性を設定しようとしましたが、役に立ちませんでした。ただし、すべてのリクエストに対して ID 属性を定数 ID 値に設定すると、問題は解決しました。

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

また

Element e1 =(Element)doc.getElementsByTagName("Assertion").item(0);
e1.setIdAttribute("ID", true);
于 2018-06-14T00:36:11.950 に答える