问题
Using spring-security-saml for handling assertions from IDP, getting below error after server is up for 1 to 2 hours. Issue is not reproducible all the time. By looking at stacktrace, issue seems to be related to parser pool used in spring saml configuration. Please share any thoughts.
library versions: opensaml 2.6.1 spring-security-saml2 1.0.0.RELEASE
parser pool config:
<bean id="parserPool" class="org.opensaml.xml.parse.StaticBasicParserPool" init-method="initialize">
<property name="builderFeatures">
<map>
<entry key="http://apache.org/xml/features/dom/defer-node-expansion" value="false"/>
</map>
</property>
</bean>
<bean id="parserPoolHolder" class="org.springframework.security.saml.parser.ParserPoolHolder"/>
org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it. at org.apache.xerces.dom.ParentNode.internalInsertBefore(Unknown Source) at org.apache.xerces.dom.ParentNode.insertBefore(Unknown Source) at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source) at org.opensaml.xml.encryption.Decrypter.parseInputStream(Decrypter.java:821) at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:599) at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:784) at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:524) at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:442) at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:403) at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141) at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69) at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:199) at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:82)
回答1:
Root cause: Multiple implementations of xerces in the project.
Found the issue. My project also has docx4j used for word document processing, docx4j changed the system property javax.xml.parsers.DocumentBuilderFactory to "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" when it is initialized and if system property is not already set and java version < 8, which internally caused to return a DocumentBuilderFactory implementation that is different from the one opensaml was initialized with. i.e org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
Fix is setting system property javax.xml.parsers.DocumentBuilderFactory to com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl by using following java runtime option
-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
回答2:
As @Srini said, the root cause is multiple implementations of xerces in the project.
I solved this by overriding the docx4j properties in docx4j.properties
:
javax.xml.parsers.DocumentBuilderFactory=org.apache.xerces.jaxp.DocumentBuilderFactoryImpl
来源:https://stackoverflow.com/questions/31060849/springsecurity-samlopensaml-failed-to-unmarshall-assertion-getting-org-w3c-d