我正在使用自定义标头发出SOAP请求,其中包含请求的安全性部分。但是,该请求现在包含两个标头,并引发以下错误:请求处理失败;嵌套的异常是org.springframework.ws.soap.client.SoapFaultClientException: No WS-安全标头,找到了根本原因。
形成的标题是:
<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);请建议我如何解决这个error.TIA!
发布于 2015-10-27 09:07:05
嗯,如果你用的是弹簧,你就得做这样的事情。在您应该拥有的ws的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>我想,编组员和解编组员对你来说应该很清楚。在你的案子中最重要的部分是
在securityPolicy.xml中,您将能够为传出//传入消息定义您所需的策略,无论是签名、usernameandpassword等等。
例如,以下文件用于使用特定证书对请求进行签名。
<?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);
}
}
}在这门课上,你可以随意改变你的标题,因为你认为合适,你就完成了.
https://stackoverflow.com/questions/33346367
复制相似问题