我使用Apache CXF 2.4.10
和wss4j 1.6.18
来使用需要添加WSA Security Addressing Elements
的外部Web服务。根据Apache的WS-SecurityPolicy文档,我需要配置一个AddressingProperties
并将其设置在requestContext
上。我正在这样做,但没有添加该元素。我做错了什么?
MyClient.java
public class MyClient
{
protected SoapService getService()
{
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(SoapService.class);
factory.setAddress(endpoint);
service = (SoapService) factory.create();
Client client = ClientProxy.getClient(this.webServiceProxy);
Endpoint cxfEndpoint = client.getEndpoint();
//logging
client.getOutInterceptors().add(new CustomLogInterceptor()); // allows me to see the SOAP Message just before it is sent
//outbound config
configureWSASecurity(factory, client, cxfEndpoint);
configureTimestamp(cxfEndpoint, client);
configureWSSecSignature(cxfEndpoint, client);
configureWSSecEncrytion(cxfEndpoint, client);
return service;
}
protected void configureWSASecurity(JaxWsProxyFactoryBean factory, Client client, Endpoint cxfEndpoint){
factory.getFeatures().add(new WSAddressingFeature());
AddressingBuilder addressingBuilder = AddressingBuilder.getAddressingBuilder();
AddressingProperties maps = addressingBuilder.newAddressingProperties();
AttributedURIType messageID = new AttributedURIType();
messageID.setValue(UUID.randomUUID().toString());
maps.setMessageID(messageID);
AttributedURIType replyTo = new AttributedURIType();
replyTo.setValue("https://webservice.com/ping");
EndpointReferenceType replyToRef = new EndpointReferenceType();
replyToRef.setAddress(replyTo);
maps.setReplyTo(replyToRef);
Map<String, Object> requestContext = ((BindingProvider) this.webServiceProxy).getRequestContext();
requestContext.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, maps);
}
protected void configureTimestamp(Endpoint cxfEndpoint, Client client){
Map<String,Object> outProps = new HashMap<String,Object>();
outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);
outProps.put(WSHandlerConstants.TTL_TIMESTAMP, "300");
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
client.getOutInterceptors().add(wssOut);
}
protected void configureWSSecSignature(Endpoint cxfEndpoint, Client client){
Map<String,Object> outProps = new HashMap<String,Object>();
WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
client.getOutInterceptors().add(wssOut);
}
@Override
public String ping(String input)
{
return this.getService().ping(input);
}
}
以下是丢失的请求元素:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-26035916F4AB4AF63814481608229281">
<wsu:Created>2015-11-22T02:53:42.927Z</wsu:Created>
<wsu:Expires>2015-11-22T02:58:42.927Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
</soap:Header>
<soap:Body>
<ping xmlns="https://webservice.com/">
<ping>success</ping>
</ping>
</soap:Body>
</soap:Envelope>
这就是请求的外观:
<wsa:MessageID xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="id-4">urn:uuid:bc57cb92-6a37-4e99-ad2d-1a0ad718264e</wsa:MessageID>
<wsa:ReplyTo xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-5">
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="id-6">http://localhost:1835/webservice/Service.asmx</wsa:To>
因为在调用factory.create()
之前没有添加addressingFeature,所以wsAddressingFeature
需要初始化为client bus
。
我在configureWSASecurity
方法中添加了这行代码:
WSAddressingFeature wsAddressingFeature = new WSAddressingFeature();
wsAddressingFeature.initialize(client, client.getBus());