使用Wss4jSecurityInterceptor会抛出WRONG_DOCUMENT_ERR:与创建该节点的节点不同的节点用于另一文档中 [英] Using Wss4jSecurityInterceptor throws a WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it

查看:83
本文介绍了使用Wss4jSecurityInterceptor会抛出WRONG_DOCUMENT_ERR:与创建该节点的节点不同的节点用于另一文档中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将应用程序升级到Java 11和Spring boot 2.1.2,并在尝试通过SOAP与外部合作伙伴通信时遇到以下错误.导致此问题的原因是Wss4jSecurityInterceptor.在运行Java 8和Spring Boot 1之前可以正常工作

I am upgrading my application to Java 11 and Spring boot 2.1.2 and running into following error when trying to communicate over SOAP to an external partner. It is the Wss4jSecurityInterceptor that causes this issue. It work before when running java 8 and Spring Boot 1

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)

java 11和Spring boot 2.1.2升级

java 11 and Spring boot 2.1.2 upgrade

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");
}

}

推荐答案

显然,wss4j-ws-security-dom中存在一个错误,该错误会在春季推出.2.2.0.

Apparently there is a bug in the wss4j-ws-security-dom that spring pulls in. 2.2.0.

我已更新到最新的版本2.2.2,并且有效:

I updated to latest version 2.2.2 and it worked:

这篇关于使用Wss4jSecurityInterceptor会抛出WRONG_DOCUMENT_ERR:与创建该节点的节点不同的节点用于另一文档中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆