Je mets à niveau mon application vers Java 11 et Spring boot 2.1.2 et je rencontre l'erreur suivante en essayant de communiquer via SOAP avec un partenaire externe. C'est le Wss4jSecurityInterceptor qui provoque ce problème. Cela fonctionne avant lors de l'exécution de java 8 et Spring Boot 1
import com.sun.xml.wss.impl.callback.PasswordCallback; import com.sun.xml.wss.impl.callback.UsernameCallback; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.handler.WSHandlerConstants; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.ws.client.core.WebServiceTemplate; import org.springframework.ws.client.core.support.WebServiceGatewaySupport; import org.springframework.ws.client.support.interceptor.ClientInterceptor; import org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor; import org.springframework.ws.transport.http.ClientHttpRequestMessageSender; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class ExampleSoapClient extends WebServiceGatewaySupport { private Wss4jSecurityInterceptor wss4jSecurityInterceptor; public ExampleSoapClient(Wss4jSecurityInterceptor wss4jSecurityInterceptor) { wss4jSecurityInterceptor = new Wss4jSecurityInterceptor(); wss4jSecurityInterceptor.setValidationCallbackHandler(new ExampleCredentialsCallbackHandler()); wss4jSecurityInterceptor.setSecurementActions(WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.USERNAME_TOKEN); /* Default Password encoding is digest, that is not supported by EP hence need to set need to set following password type. */ wss4jSecurityInterceptor.setSecurementPasswordType(WSConstants.PASSWORD_TEXT); wss4jSecurityInterceptor.setSecurementUsernameTokenNonce(false); wss4jSecurityInterceptor.setSecurementUsername("username"); wss4jSecurityInterceptor.setSecurementPassword("password"); //Note! this will help our external mock to not need any security implementation wss4jSecurityInterceptor.setSecurementMustUnderstand(false); SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(40000); requestFactory.setReadTimeout(40000); setMessageSender(new ClientHttpRequestMessageSender(requestFactory)); } public Object sendRequest(Object request) { final WebServiceTemplate webServiceTemplate = getWebServiceTemplate(); ClientInterceptor[] interceptors = new ClientInterceptor[1]; interceptors[0] = wss4jSecurityInterceptor; webServiceTemplate.setInterceptors((interceptors)); final SubmitDocument submitDocument = createRequest(request); final SubmitDocumentResponse submitDocumentResponse = (SubmitDocumentResponse) webServiceTemplate.marshalSendAndReceive(endpoint, submitDocument); return response; } } class ExampleCredentialsCallbackHandler implements CallbackHandler { public ExampleCredentialsCallbackHandler() { } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback callback : callbacks) { if (callback instanceof UsernameCallback) { handleUsernameCallback((UsernameCallback) callback); } else if (callback instanceof PasswordCallback) { handlePasswordCallback((PasswordCallback) callback); } else { throw new UnsupportedCallbackException(callback); } } } private void handleUsernameCallback(UsernameCallback callback) { callback.setUsername("username"); } private void handlePasswordCallback(PasswordCallback callback) { callback.setPassword("password"); }
mise à jour java 11 et Spring boot 2.1.2
REQUEST: ExampleSoapClient.sendRequest([javax.xml.bind.JAXBElement@5bba179f]). ERROR: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it. org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it. at java.xml/com.sun.org.apache.xerces.internal.dom.ParentNode.internalInsertBefore(ParentNode.java:356) at java.xml/com.sun.org.apache.xerces.internal.dom.ParentNode.insertBefore(ParentNode.java:287) at java.xml/com.sun.org.apache.xerces.internal.dom.NodeImpl.appendChild(NodeImpl.java:237) at org.apache.wss4j.dom.util.WSSecurityUtil.prependChildElement(WSSecurityUtil.java:314) at org.apache.wss4j.dom.util.WSSecurityUtil.findWsseSecurityHeaderBlock(WSSecurityUtil.java:435) at org.apache.wss4j.dom.message.WSSecHeader.insertSecurityHeader(WSSecHeader.java:165) at org.apache.wss4j.dom.handler.WSHandler.doSenderAction(WSHandler.java:117) at org.springframework.ws.soap.security.wss4j2.Wss4jHandler.doSenderAction(Wss4jHandler.java:63) at org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor.secureMessage(Wss4jSecurityInterceptor.java:574) at org.springframework.ws.soap.security.AbstractWsSecurityInterceptor.handleRequest(AbstractWsSecurityInterceptor.java:210) at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:597) at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390) at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:378) at com.example.domain.integration.provider.ExampleSoapClient.sendRequest(ExampleportSoapClient.java:61)
} p >
3 Réponses :
Apparemment, il y a un bogue dans le wss4j-ws-security-dom qui se déclenche. 2.2.0.
J'ai mis à jour la dernière version 2.2.2 et cela a fonctionné:
Peut également revenir à la version 2.0.6 et fonctionner.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> <version>2.0.6.RELEASE</version> </dependency>
Il y a aussi un problème lors de l'utilisation avec la nouvelle version saaj-impl (v1.4.0 ou supérieure).
<dependency> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> <version>1.3.28</version> </dependency>
Cette version spécifique m'a sauvé la vie! Merci.