【问题标题】:Custom soapHeader for a soap request with Spring使用 Spring 进行肥皂请求的自定义 soapHeader
【发布时间】:2015-10-26 12:58:08
【问题描述】:

我正在使用包含请求的安全部分的自定义标头发出 SOAP 请求。 但是该请求现在包含两个标头并引发以下错误: [请求处理失败;嵌套异常是 org.springframework.ws.soap.client.SoapFaultClientException: No WS-Security header found] 根本原因

形成的标题是:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header><soapenv:Envelope xmlns:ser="dasdasdasd" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Header><wsse:Security xmlns:wsse="asdasdasdas" soapenv:mustUnderstand="1">  <wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-2"><wsse:Username>test</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">adasdasdasdasd</wsse:Password><wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">!@#!@#@#$@!#!@@%*(&*&^%#$@#</wsse:Nonce><wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created></wsse:UsernameToken></wsse:Security></soapenv:Header></soapenv:Envelope></SOAP-ENV:Header><SOAP-ENV:Body><ns2:CreateSaleOrderRequest xmlns:ns2="http://uniware.unicommerce.com/services/"><ns2:SaleOrder><ns2:DisplayOrderCode>200</ns2:DisplayOrderCode></ns2:SaleOrder></ns2:CreateSaleOrderRequest></SOAP-ENV:Body></SOAP-ENV:Envelope>

我的上述请求的代码如下:

private static final String uri = "http://requestb.in/1eh2un81";

public String createSaleOrder(Suborder suborder)
{
    SaleOrder saleorder = new SaleOrder();
    saleorder = setSaleOrderObject(suborder);
    CreateSaleOrderRequest request = new CreateSaleOrderRequest();
    request.setSaleOrder(saleorder);
    String response = this.getWebServiceTemplate().marshalSendAndReceive(uri, request, 
            new WebServiceMessageCallback() {
                public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException 
        {
                    SoapMessage soapmessage = (SoapMessage)message;                
                    SoapHeader header = soapmessage.getSoapHeader();
                    //soapmessage.getEnvelope().addAttribute(, "soapenv");

                    StringBuilder soapheader = new StringBuilder();
                    soapheader.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"zsdasdasdasd">");
                    soapheader.append("<soapenv:Header>");
                    soapheader.append("<wsse:Security soapenv:mustUnderstand=\"1\" xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">  ");
                    soapheader.append("<wsse:UsernameToken wsu:Id=\"UsernameToken-2\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\">");
                    soapheader.append("<wsse:Username>test</wsse:Username>");
                    soapheader.append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText\">adasdasdasdasd</wsse:Password>");
                    soapheader.append("<wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">!2312312!@#!@#!#$@#%R</wsse:Nonce>");
                    soapheader.append("<wsu:Created>2014-09-04 T1015.41.649Z</wsu:Created>");
                    soapheader.append("</wsse:UsernameToken>");
                    soapheader.append("</wsse:Security>");
                    soapheader.append("</soapenv:Header>");
                    soapheader.append("</soapenv:Envelope>");


                    StringSource HeaderSource = new StringSource(soapheader.toString());
                    Transformer transformer = TransformerFactory.newInstance().newTransformer();
                    transformer.transform(HeaderSource,header.getResult());

                    }
    }).toString();
    System.out.println(response);

请建议我如何解决此错误。TIA!

【问题讨论】:

    标签: java xml spring web-services soap


    【解决方案1】:

    嗯,如果您使用的是 spring,您将不得不在您的 xml 中进行类似的操作,以获得您应该拥有的 ws:

        <bean id="YourWsClientBean" class="eu.europa.acer.aris.dciws.client.DciWsClient">
            <constructor-arg ref="webServiceTemplate"></constructor-arg>
        </bean>
    
    
        <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
            <constructor-arg ref="messageFactory"/>
            <property name="marshaller" ref="marshaller"></property>
            <property name="unmarshaller" ref="unMarshaller"></property>
    
            <property name="messageSender">
                <bean
                    class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
                </bean>
            </property>
             <!-- NON PROXY
             <property name="messageSender" ref = "httpSender"></property>    -->       
            <property name="defaultUri" value="https://testframework.test-acer-remit.eu/dci-ws/" />
            <property name="interceptors">
                <list>
                    <ref bean="securityConfInterceptor" />
    
                </list>
            </property>
        </bean>
    
        <bean id="securityConfInterceptor" class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
                <property name="policyConfiguration" value="classpath:securityPolicy.xml" />
                <property name="callbackHandlers">
                    <!-- <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler"> 
                        <property name="keyStore" ref="keyStore" /> <property name="privateKeyPassword" 
                        value="changeit" /> <property name="trustStore" ref="trustStore" /> </bean> -->
                    <list>
                        <ref bean="keyStoreHandler"/> 
                    </list>
                </property>
        </bean>
    

    marshaller 和 unmarshaller 我想你应该很清楚。 在你的情况下最重要的部分是

    在 securityPolicy.xml 中,您将能够为传出//传入消息定义您想要的策略,例如签名、用户名和密码等。

    例如以下文件用于使用特定证书对请求进行签名。

    <?xml version="1.0" encoding="UTF-8"?>
        <!-- <xwss:SecurityConfiguration dumpMessages="false" xmlns:xwss="http://java.sun.com/xml/ns/xwss/config"> 
            <xwss:Sign includeTimestamp="false"> <xwss:X509Token certificateAlias="ceremp 
            staging ca"/> </xwss:Sign> </xwss:SecurityConfiguration> -->
        <xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
            <!-- <xwss:RequireTimestamp maxClockSkew="60" timestampFreshnessLimit="300"/> 
                <xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/> 
                <xwss:Timestamp /> <xwss:UsernameToken name="mojo" password="mojopass" digestPassword="true" 
                useNonce="true"/> -->
            <xwss:Sign>
                <xwss:X509Token certificateAlias="acerprivate" /> 
                <!-- <xwss:X509Token certificateAlias="acer staging cert" /> -->
                <xwss:CanonicalizationMethod algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                <xwss:SignatureMethod algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
                <xwss:SignatureTarget type="xpath"
                    value="./SOAP-ENV:Envelope/SOAP-ENV:Body">
                    <xwss:DigestMethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
                    <xwss:Transform algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116">
                        <xwss:AlgorithmParameter name="XPATH"
                            value="./SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature[1]/ds:KeyInfo/wsse:SecurityTokenReference" />
                    </xwss:Transform>
                    <xwss:Transform
                        algorithm="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#STR-Transform">
                        <xwss:AlgorithmParameter name="CanonicalizationMethod"
                            value="http://www.w3.org/2001/10/xml-exc-c14n#" />
                    </xwss:Transform>
                </xwss:SignatureTarget>
            </xwss:Sign>
        </xwss:SecurityConfiguration>
    

    希望这对您有所帮助。

    有时我建议一些 ws 的新同事采用肮脏的替代方案,如果他们想让更改尽可能简单。 例如。这是来自春季论坛-->

            public void sendAndReceiveXMLPayload(String xmlFileNamePath) throws IOException {
    
            ClassPathResource
                classPathResource =
                    new ClassPathResource(xmlFileNamePath);
    
            Source
                requestSource = 
                    new ResourceSource(classPathResource);
    
            StringResult
                result =
                    new StringResult();
    
            getWebServiceTemplate().
                sendSourceAndReceiveToResult(
                    requestSource,  
                    new WSSESecurityHeaderRequestWebServiceMessageCallback(),
                    result
                );  
        }
    

    通知WSSESecurityHeaderRequestWebServiceMessageCallback

    定义一个

    public class WSSESecurityHeaderRequestWebServiceMessageCallback implements WebServiceMessageCallback {
    
        public void doWithMessage(WebServiceMessage message) throws IOException, TransformerException {
    
            try {
    
                // Assumption: We are using the default SAAJWebMessageFactory 
    
                SaajSoapMessage
                    saajSoapMessage =
                        (SaajSoapMessage)message;
    
                SOAPMessage
                    soapMessage =
                        saajSoapMessage.getSaajMessage();
    
                SOAPPart
                    soapPart =
                        soapMessage.getSOAPPart();
    
                SOAPEnvelope
                    soapEnvelope =
                        soapPart.getEnvelope();
    
                SOAPHeader
                    soapHeader =
                        soapEnvelope.getHeader();
    
                Name
                    headerElementName =
                        soapEnvelope.createName(
                            "Security",
                            "wsse",
                            "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                        );
    
                // Add "Security" soapHeaderElement to soapHeader
                SOAPHeaderElement
                    soapHeaderElement =
                        soapHeader.addHeaderElement(headerElementName);
    
                // This may be important for some portals!
                soapHeaderElement.setActor(null);
    
                // Add usernameToken to "Security" soapHeaderElement 
                SOAPElement
                    usernameTokenSOAPElement =
                        soapHeaderElement.addChildElement("UsernameToken");
    
                // Add username to usernameToken
                SOAPElement
                    userNameSOAPElement =
                        usernameTokenSOAPElement.addChildElement("Username");
    
                userNameSOAPElement.addTextNode("myUserName");
    
                // Add password to usernameToken
                SOAPElement
                    passwordSOAPElement =
                        usernameTokenSOAPElement.addChildElement("Password");
    
                passwordSOAPElement.addTextNode("myPassword");
    
            } catch (SOAPException soapException) {
                throw new RuntimeException("WSSESecurityHeaderRequestWebServiceMessageCallback", soapException);
            }
        }
    }
    

    在本课程中,您可以随意更改您认为合适的标题,然后您就完成了...

    【讨论】:

    • 您好,感谢您的回复。按照您所说的,我们如何在 中添加 wsu:Id="UsernameToken-EF9408A24B65E1B26A14454250497141" 等属性
    猜你喜欢
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多