我正在使用包含请求安全部分的自定义标头发出SOAP请求。 但请求现在包含两个标头,并抛出以下错误: [请求处理失败;嵌套异常是org.springframework.ws.soap.client.SoapFaultClientException:没有找到WS-Security标头]有根本原因
形成的标题是:
<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!
答案 0 :(得分:0)
嗯,如果你使用弹簧,你就必须这样做..你的xml里面应该有你应该拥有的:
<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>
希望这能为你提供一个普遍的概念。
有时候,如果他们想让改变尽可能简单的话,我建议一些新的同事采取肮脏的选择。 例如。这是来自春季论坛 - &gt;
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);
}
}
}
在本课程中,您可以根据自己的需要更改自己对标题的处理方式并完成...