我只是发送一个ws客户端,它向一些网址发送请求:
@SuppressWarnings("unchecked")
private JAXBElement<O> sendSyncSoapRequest(final JAXBElement<I> req, final String iszrUrl) {
if (iszrUrl != null) {
return (JAXBElement<O>) this.wsTemplate.marshalSendAndReceive(iszrUrl, req);
} else {
return (JAXBElement<O>) this.wsTemplate.marshalSendAndReceive(req);
}
}
现在我需要将附加证书链附加到soap请求中。我该怎么做?请帮忙
答案 0 :(得分:1)
所以我已经解决了这个问题。我需要用新的httpClient创建WebServiceMessageSender,其中包含带有证书的sslFactory:
WebServiceMessageSender sender = new HttpComponentsMessageSender(HttpClients.custom()
.addInterceptorFirst(new RemoveSoapHeadersInterceptor()).setSSLSocketFactory(factory));
wsTemplate.setMessageSender(sender);
// copy & paste from HttpComponentsMessageSender:
/**
* HttpClient {@link org.apache.http.HttpRequestInterceptor} implementation that removes {@code Content-Length} and
* {@code Transfer-Encoding} headers from the request. Necessary, because SAAJ and other SOAP implementations set
* these headers themselves, and HttpClient throws an exception if they have been set.
*/
public static class RemoveSoapHeadersInterceptor implements HttpRequestInterceptor {
@Override
public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
if (request instanceof HttpEntityEnclosingRequest) {
if (request.containsHeader(HTTP.TRANSFER_ENCODING)) {
request.removeHeaders(HTTP.TRANSFER_ENCODING);
}
if (request.containsHeader(HTTP.CONTENT_LEN)) {
request.removeHeaders(HTTP.CONTENT_LEN);
}
}
}
}
答案 1 :(得分:0)
我不知道Spring在客户端上使用证书身份验证的任何语法糖。然而现在可能有一些我错过的东西。如果没有其他人指出您可以将一个简单的注释应用到您的Web服务模板,这就是我的想法。
这不是一个完全一步一步的答案,但它应该让你在那里分道扬..通过使用WebServiceMessageCallback,您可以在发送消息之前修改SOAP消息中的标头。下面的代码演示了如何在标题中添加用户名和密码。
您应该能够使用相同的机制以类似的方式将证书添加到安全标头中。请查看以下文档,该文档解释了基于SOAP证书的身份验证,并在第9页上显示了此示例安全标头。
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0.pdf
Object response = getWebServiceTemplate().marshalSendAndReceive(
exposureRequests,
new WebServiceMessageCallback() {
/**
* The doWithMessage callback enables us to modify the message after it has
* been built using the nice Spring/JAXB marshalling, just before it gets
* sent out.
*/
@Override
public void doWithMessage(WebServiceMessage message)
throws IOException, TransformerException {
applySecurityHeaders(message, SOAP_ACTION);
}
}
);
/**
* Add security headers to the outgoing message, so that the client is
* authenticated against the web service.
*/
private void applySecurityHeaders(WebServiceMessage message, String soapAction)
throws IOException, TransformerException {
Assert.isInstanceOf(SoapMessage.class, message);
SoapMessage soapMessage = (SoapMessage) message;
soapMessage.setSoapAction(soapAction);
SoapHeader header = soapMessage.getSoapHeader();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(getSecurityHeaderSource(), header.getResult());
soapMessage.writeTo(new LoggingOutputStream(log));
}
/**
* Returns the content required for a basic SOAP security header.
*/
private StringSource getSecurityHeaderSource() {
return new StringSource(
"<Security xmlns=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\">\n "
+ "<UsernameToken>\n"
+ "<Username><![CDATA[" + username + "]]></Username>\n "
+ "<Password><![CDATA[" + password + "]]></Password>\n "
+ "</UsernameToken>\n"
+ "</Security>\n");
}