Spring-WS:如何发送已经封装好的消息?
Spring-WS: How to send an already enveloped message?
我实现了一个 Spring-WS Web 服务客户端并且我发送了一个没有解组的请求,因为我正在发送一个带有所有 SOAP 包装器的现成签名 (wssec) 请求。
例如:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<wsse:Security wsu:Id="Id-sec-98b44dc4123d94b309db4e47881c48c0cfde" SOAP-ENV:actor="http://smev.gosuslugi.ru/actors/smev">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Id-sig-02747f3e4b2c3afbd9ee0c47b82df6ce1ce1">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
<Reference URI="#Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0" Id="Id-dataref-2f98695f5d03929ba61e8553e17275e99ea0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
<DigestValue>DIGECT</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>SIG_VALUE</SignatureValue>
<KeyInfo Id="Id-keyinfo-60c321e68eba4e0b869013c3b661a255d39a">
<wsse:SecurityTokenReference wsu:Id="Id-strT8lVAuhyhE9ORsox">
<wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#Id-bstKf4S_QPNjJpr839_"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="Id-bstKf4S_QPNjJpr839_">CERT</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0">
<Message/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
但是根据Spring-WS documentation中定义的算法,Spring-WS通过调用WebServiceTemplate
中的createWebServiceMessage()
将我的请求另外包装在信封中。
发送结果如下:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<wsse:Security wsu:Id="Id-sec-98b44dc4123d94b309db4e47881c48c0cfde" SOAP-ENV:actor="http://smev.gosuslugi.ru/actors/smev">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Id-sig-02747f3e4b2c3afbd9ee0c47b82df6ce1ce1">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
<Reference URI="#Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0" Id="Id-dataref-2f98695f5d03929ba61e8553e17275e99ea0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
<DigestValue>DIGECT</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>SIG_VALUE</SignatureValue>
<KeyInfo Id="Id-keyinfo-60c321e68eba4e0b869013c3b661a255d39a">
<wsse:SecurityTokenReference wsu:Id="Id-strT8lVAuhyhE9ORsox">
<wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#Id-bstKf4S_QPNjJpr839_"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="Id-bstKf4S_QPNjJpr839_">CERT</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0">
<Message/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我是这样做的:
public void callWebService(String request) {
StreamSource source = new StreamSource(new StringReader(request));
StreamResult result = new StreamResult(System.out);
getWebServiceTemplate().sendSourceAndReceiveToResult(source, webServiceMessage -> {
SaajSoapMessage saajMessage = (SaajSoapMessage) webServiceMessage;
saajMessage.setSoapAction(SOAP_ACTION);
}, result);
在我看来,使用 SAAJ 无济于事。我怎样才能发送我的请求?谢谢!
我自己找到了解决方案。它包括构建新的 SAAJ 消息并将其替换为旧消息。我希望有人会有所帮助。
public void callWebService(String request) {
StreamSource source = new StreamSource(new StringReader(request));
StreamResult result = new StreamResult(System.out);
getWebServiceTemplate().sendSourceAndReceiveToResult(source, webServiceMessage -> {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) webServiceMessage;
try {
SOAPPart soapPart = saajSoapMessage.getSaajMessage().getSOAPPart();
SOAPBody soapBody = soapPart.getEnvelope().getBody();
Document innerSoapBody = soapBody.extractContentAsDocument();
//Строим новое SAAJ-сообщение for webServiceMessage
MessageFactory soapMessageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = soapMessageFactory.createMessage();
soapMessage.getSOAPPart().setContent(new DOMSource(innerSoapBody));
((SaajSoapMessage) webServiceMessage).setSaajMessage(soapMessage);
} catch (SOAPException e) {
LOGGER.error("Can't rebuild WebServiceMessage in SMEV2 invoke!");
e.printStackTrace();
}
//Передаим корректный SOAP-Action.
saajSoapMessage.setSoapAction(SMEV2_SOAP_ACTION);
}, result);
我实现了一个 Spring-WS Web 服务客户端并且我发送了一个没有解组的请求,因为我正在发送一个带有所有 SOAP 包装器的现成签名 (wssec) 请求。
例如:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<wsse:Security wsu:Id="Id-sec-98b44dc4123d94b309db4e47881c48c0cfde" SOAP-ENV:actor="http://smev.gosuslugi.ru/actors/smev">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Id-sig-02747f3e4b2c3afbd9ee0c47b82df6ce1ce1">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
<Reference URI="#Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0" Id="Id-dataref-2f98695f5d03929ba61e8553e17275e99ea0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
<DigestValue>DIGECT</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>SIG_VALUE</SignatureValue>
<KeyInfo Id="Id-keyinfo-60c321e68eba4e0b869013c3b661a255d39a">
<wsse:SecurityTokenReference wsu:Id="Id-strT8lVAuhyhE9ORsox">
<wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#Id-bstKf4S_QPNjJpr839_"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="Id-bstKf4S_QPNjJpr839_">CERT</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0">
<Message/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
但是根据Spring-WS documentation中定义的算法,Spring-WS通过调用WebServiceTemplate
中的createWebServiceMessage()
将我的请求另外包装在信封中。
发送结果如下:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<wsse:Security wsu:Id="Id-sec-98b44dc4123d94b309db4e47881c48c0cfde" SOAP-ENV:actor="http://smev.gosuslugi.ru/actors/smev">
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="Id-sig-02747f3e4b2c3afbd9ee0c47b82df6ce1ce1">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34102012-gostr34112012-256"/>
<Reference URI="#Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0" Id="Id-dataref-2f98695f5d03929ba61e8553e17275e99ea0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="urn:ietf:params:xml:ns:cpxmlsec:algorithms:gostr34112012-256"/>
<DigestValue>DIGECT</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>SIG_VALUE</SignatureValue>
<KeyInfo Id="Id-keyinfo-60c321e68eba4e0b869013c3b661a255d39a">
<wsse:SecurityTokenReference wsu:Id="Id-strT8lVAuhyhE9ORsox">
<wsse:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#Id-bstKf4S_QPNjJpr839_"/>
</wsse:SecurityTokenReference>
</KeyInfo>
</Signature>
<wsse:BinarySecurityToken ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="Id-bstKf4S_QPNjJpr839_">CERT</wsse:BinarySecurityToken>
</wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body wsu:Id="Id-wssecdata-d8392bad08e2095ea110d7ebdf6cb20b77f0">
<Message/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我是这样做的:
public void callWebService(String request) {
StreamSource source = new StreamSource(new StringReader(request));
StreamResult result = new StreamResult(System.out);
getWebServiceTemplate().sendSourceAndReceiveToResult(source, webServiceMessage -> {
SaajSoapMessage saajMessage = (SaajSoapMessage) webServiceMessage;
saajMessage.setSoapAction(SOAP_ACTION);
}, result);
在我看来,使用 SAAJ 无济于事。我怎样才能发送我的请求?谢谢!
我自己找到了解决方案。它包括构建新的 SAAJ 消息并将其替换为旧消息。我希望有人会有所帮助。
public void callWebService(String request) {
StreamSource source = new StreamSource(new StringReader(request));
StreamResult result = new StreamResult(System.out);
getWebServiceTemplate().sendSourceAndReceiveToResult(source, webServiceMessage -> {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) webServiceMessage;
try {
SOAPPart soapPart = saajSoapMessage.getSaajMessage().getSOAPPart();
SOAPBody soapBody = soapPart.getEnvelope().getBody();
Document innerSoapBody = soapBody.extractContentAsDocument();
//Строим новое SAAJ-сообщение for webServiceMessage
MessageFactory soapMessageFactory = MessageFactory.newInstance();
SOAPMessage soapMessage = soapMessageFactory.createMessage();
soapMessage.getSOAPPart().setContent(new DOMSource(innerSoapBody));
((SaajSoapMessage) webServiceMessage).setSaajMessage(soapMessage);
} catch (SOAPException e) {
LOGGER.error("Can't rebuild WebServiceMessage in SMEV2 invoke!");
e.printStackTrace();
}
//Передаим корректный SOAP-Action.
saajSoapMessage.setSoapAction(SMEV2_SOAP_ACTION);
}, result);