【问题标题】:Spring WS how to get server side soap response xml for adding soap header with signSpring WS如何获取服务器端soap响应xml以添加带有符号的soap标头
【发布时间】:2015-04-08 11:13:04
【问题描述】:

我有 spring 网络服务。我需要签署服务器(我的网络服务)为肥皂请求提供的肥皂响应。 xwss 和 wss4j 拦截器不适合这个,因为我需要这种格式:

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gost34310-gost34311"/>
<ds:Reference URI="#b0525e8a-dbcb-45da-abfd-d1bdecf6ccbb">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"/>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#gost34311"/>
<ds:DigestValue>valval=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
valuevalue==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
valuevaluevalue=
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>

我需要在我的回复中将此添加到肥皂标题块中。为此,我必须获取整个soap响应的xml,包括soap env等。

如何获取该xml,通过添加soap标头对其进行修改,最后将其作为响应发送?

请帮帮我

【问题讨论】:

    标签: java xml spring web-services spring-ws


    【解决方案1】:

    好的,我终于用自定义 SmartSoapEndpointInterceptor 解决了这个问题。我创建了实现 SmartSoapEndpointInterceptor 的 MyCustomEndpointInterceptor 并根据我的需要更改了 handleResponse。源代码为:

    public class MyCustomEndpointInterceptor implements SmartSoapEndpointInterceptor {
    
        @Override
        public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
            return true;
        }
    
        @Override
        public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
            SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
            DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(strMsg);
            Document doc = soapResponse.getDocument();
            // Look for the SOAP header
            Element headerElement = null;
            NodeList nodes = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Header");
            if (nodes.getLength() == 0) {
                System.out.println("Adding a SOAP Header Element");
                headerElement = doc.createElementNS("http://schemas.xmlsoap.org/soap/envelope/", "Header");
                nodes = doc.getElementsByTagNameNS("http://schemas.xmlsoap.org/soap/envelope/", "Envelope");
                if (nodes != null) {
                    Element envelopeElement = (Element) nodes.item(0);
                    headerElement.setPrefix(envelopeElement.getPrefix());
                    envelopeElement.appendChild(headerElement);
                }
            } else {
                System.out.println("Found " + nodes.getLength() + " SOAP Header elements.");
                headerElement = (Element) nodes.item(0);
            }
    
            Provider kncaProvider = new IolaProvider();
            Security.addProvider(kncaProvider);
    
            KeyStore ks = KeyStore.getInstance("pkcs12", kncaProvider.getName());
    
            ks.load(new FileInputStream(keypath), keypass.toCharArray());
    
            PrivateKey privateKey = (PrivateKey) ks.getKey(keyalias, keypass.toCharArray());
    
            XMLSignature sig = new XMLSignature(doc, "", "http://www.w3.org/2001/04/xmldsig-more#gost34310-gost34311");
            headerElement.appendChild(sig.getElement());
            Transforms transforms = new Transforms(doc); 
            transforms.addTransform("http://www.w3.org/2000/09/xmldsig#enveloped-signature");
            transforms.addTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments");
            sig.addDocument("", transforms,"http://www.w3.org/2001/04/xmldsig-more#gost34311"); 
            X509Certificate cert = (X509Certificate) ks.getCertificate(somealias);
            sig.addKeyInfo(cert); 
            sig.sign(privateKey);
    
            return true;
        }
    
        @Override
        public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
            return true;
        }
    
        @Override
        public boolean shouldIntercept(MessageContext messageContext, Object endpoint) {
            return true;
        }
    
        @Override
        public boolean understands(SoapHeaderElement header) {
            return true;
        }
    }
    

    【讨论】:

    • 搜索了几个小时后,我找到了你的答案,它终于对我有用了:) 你有使用 trustkeystore 解密响应内容的解决方案吗?我非常接近我的解决方案。谢谢。
    【解决方案2】:

    使用 spring-ws,您可以将 MessageContext messageContext 参数添加到任何处理soap请求的方法:

    @PayloadRoot(localPart = LOCAL_PART, namespace = NAMESPACE)
    @ResponsePayload
    public <return type> handleRequest(@RequestPayload final <request type> request,
                                             MessageContext messageContext)
    

    使用消息上下文,您可以检索响应标头并根据需要对其进行编辑。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多